library(ggplot2)
library(grid)
library(forestploter)
library(tidyverse)
saveto <- "/Volumes/Research Project/IAT_Retest/Plotting/SavedFigs/"
path <- "/Volumes/"
setwd(paste0(path,"Research Project/IAT_Retest/Estimates/UCR/"))
Warning: The working directory was changed to /Volumes/Research Project/IAT_Retest/Estimates/UCR inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
Cal1 <-read.csv("IndividualParametersQuadUCR1.csv", header = T)
Cal2 <-read.csv("IndividualParametersQuadUCR2.csv", header = T)

colnames(Cal1)[2:ncol(Cal1)]<-paste(colnames(Cal1[2:ncol(Cal1)]),"T1",sep="_")
colnames(Cal2)[2:ncol(Cal2)]<-paste(colnames(Cal2[2:ncol(Cal2)]),"T2",sep="_")

Q.Cal <- merge(Cal1, Cal2, by = "subject", all.x = T, all.y = T)

setwd(paste0(path,"Research Project/IAT_Retest/Estimates/PI/"))
PI1 <- read.csv("IndividualParametersQuadProjectImplicit1.csv")
PI2 <- read.csv("IndividualParametersQuadProjectImplicit2.csv")

colnames(PI1)[2:ncol(PI1)]<-paste(colnames(PI1[2:ncol(PI1)]),"T1",sep="_")
colnames(PI2)[2:ncol(PI2)]<-paste(colnames(PI2[2:ncol(PI2)]),"T2",sep="_")

Q.PI <- merge(PI1, PI2, by = "ID", all.x = T, all.y = T)

setwd(paste0(path,"Research Project/IAT_Retest/Estimates/Gawronski/"))
Gaw1 <- read.csv("IndividualParametersQuadGawronski1.csv")
Gaw2 <- read.csv("IndividualParametersQuadGawronski2.csv")

colnames(Gaw1)[2:ncol(Gaw1)]<-paste(colnames(Gaw1[2:ncol(Gaw1)]),"T1",sep="_")
colnames(Gaw2)[2:ncol(Gaw2)]<-paste(colnames(Gaw2[2:ncol(Gaw2)]),"T2",sep="_")

Q.Gaw <- merge(Gaw1, Gaw2, by = "code", all.x = T, all.y = T)

setwd(paste0(path,"Research Project/IAT_Retest/Estimates/Forscher/"))
For1<-read.csv("IndividualParametersQuadForscher1.csv", header = T)
For2<-read.csv("IndividualParametersQuadForscher2.csv", header = T)

colnames(For1)[2:ncol(For1)]<-paste(colnames(For1[2:ncol(For1)]),"T1",sep="_")
colnames(For2)[2:ncol(For2)]<-paste(colnames(For2[2:ncol(For2)]),"T2",sep="_")

Q.For <- merge(For1, For2, by = "subject", all.x = T, all.y = T)

setwd(paste0(path,"Research Project/IAT_Retest/Estimates/Lai1/"))
Lai11<-read.csv("IndividualParametersLaiStudy1Quad1.csv", header = T)
Lai12<-read.csv("IndividualParametersLaiStudy1Quad2.csv", header = T)

colnames(Lai11)[2:ncol(Lai11)]<-paste(colnames(Lai11[2:ncol(Lai11)]),"T1",sep="_")
colnames(Lai12)[2:ncol(Lai12)]<-paste(colnames(Lai12[2:ncol(Lai12)]),"T2",sep="_")

Q.Lai1 <- merge(Lai11, Lai12, by = "session_id", all.x = T, all.y = T)

setwd(paste0(path,"Research Project/IAT_Retest/Estimates/Lai2/"))
Lai21<-read.csv("IndividualParametersLaiStudy2Quad1.csv", header = T)
Lai22<-read.csv("IndividualParametersLaiStudy2Quad2.csv", header = T)

colnames(Lai21)[2:ncol(Lai21)]<-paste(colnames(Lai21[2:ncol(Lai21)]),"T1",sep="_")
colnames(Lai22)[2:ncol(Lai22)]<-paste(colnames(Lai22[2:ncol(Lai22)]),"T2",sep="_")

Q.Lai2 <- merge(Lai21, Lai22, by = "session_id", all.x = T, all.y = T)

colnames(Q.Cal)[1] <- "subID"
Q.Cal <- cbind(Q.Cal, Study = "Calanchini")
colnames(Q.PI)[1] <- "subID"
Q.PI <- cbind(Q.PI, Study = "PI")
colnames(Q.Gaw)[1] <- "subID"
Q.Gaw <- cbind(Q.Gaw, Study = "Gawronski")
colnames(Q.For)[1] <- "subID"
Q.For <- cbind(Q.For, Study = "Forscher")
colnames(Q.Lai1)[1] <- "subID"
Q.Lai1 <- cbind(Q.Lai1, Study = "Lai 1")
colnames(Q.Lai2)[1] <- "subID"
Q.Lai2 <- cbind(Q.Lai2, Study = "Lai 2")

Quad <- rbind(Q.Cal,Q.PI,Q.Gaw,Q.For,Q.Lai1,Q.Lai2)


Quad$Study[Quad$Study=="PI"]<-"Project Implicit, 2020"
Quad$Study[Quad$Study=="Calanchini"]<-"Wilson & Calanchini, 2022"
Quad$Study[Quad$Study=="Lai 1"]<-"Lai et al., 2016 (Study 1)  "
Quad$Study[Quad$Study=="Lai 2"]<-"Lai et al., 2016 (Study 2)  "
Quad$Study[Quad$Study=="Gawronski"]<-"Gawronski et al., 2017"
Quad$Study[Quad$Study=="Forscher"]<-"Forscher et al., 2017"
path <- "/Volumes/"
setwd(paste0(path,"Research Project/IAT_Retest/Estimates/UCR/"))
Warning: The working directory was changed to /Volumes/Research Project/IAT_Retest/Estimates/UCR inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
Cal1 <-read.csv("IndividualParametersPDUCR1.csv", header = T)
Cal2 <-read.csv("IndividualParametersPDUCR2.csv", header = T)

colnames(Cal1)[2:ncol(Cal1)]<-paste(colnames(Cal1[2:ncol(Cal1)]),"T1",sep="_")
colnames(Cal2)[2:ncol(Cal2)]<-paste(colnames(Cal2[2:ncol(Cal2)]),"T2",sep="_")

P.Cal <- merge(Cal1, Cal2, by = "subject", all.x = T, all.y = T)

setwd(paste0(path,"Research Project/IAT_Retest/Estimates/PI/"))
PI1 <- read.csv("IndividualParametersProjectImplicitPD1.csv")
PI2 <- read.csv("IndividualParametersProjectImplicitPD2.csv")

colnames(PI1)[2:ncol(PI1)]<-paste(colnames(PI1[2:ncol(PI1)]),"T1",sep="_")
colnames(PI2)[2:ncol(PI2)]<-paste(colnames(PI2[2:ncol(PI2)]),"T2",sep="_")

P.PI <- merge(PI1, PI2, by = "ID", all.x = T, all.y = T)

setwd(paste0(path,"Research Project/IAT_Retest/Estimates/Gawronski/"))
Gaw1 <- read.csv("IndividualParametersPDGawronski1.csv")
Gaw2 <- read.csv("IndividualParametersPDGawronski2.csv")

colnames(Gaw1)[2:ncol(Gaw1)]<-paste(colnames(Gaw1[2:ncol(Gaw1)]),"T1",sep="_")
colnames(Gaw2)[2:ncol(Gaw2)]<-paste(colnames(Gaw2[2:ncol(Gaw2)]),"T2",sep="_")

P.Gaw <- merge(Gaw1, Gaw2, by = "code", all.x = T, all.y = T)

setwd(paste0(path,"Research Project/IAT_Retest/Estimates/Forscher/"))
For1<-read.csv("IndividualParametersForscherPD1.csv", header = T)
For2<-read.csv("IndividualParametersForscherPD2.csv", header = T)

colnames(For1)[2:ncol(For1)]<-paste(colnames(For1[2:ncol(For1)]),"T1",sep="_")
colnames(For2)[2:ncol(For2)]<-paste(colnames(For2[2:ncol(For2)]),"T2",sep="_")

P.For <- merge(For1, For2, by = "subject", all.x = T, all.y = T)

setwd(paste0(path,"Research Project/IAT_Retest/Estimates/Lai1/"))
Lai11<-read.csv("IndividualParametersLaiStudy1PD1.csv", header = T)
Lai12<-read.csv("IndividualParametersLaiStudy1PD2.csv", header = T)

colnames(Lai11)[2:ncol(Lai11)]<-paste(colnames(Lai11[2:ncol(Lai11)]),"T1",sep="_")
colnames(Lai12)[2:ncol(Lai12)]<-paste(colnames(Lai12[2:ncol(Lai12)]),"T2",sep="_")

P.Lai1 <- merge(Lai11, Lai12, by = "session_id", all.x = T, all.y = T)

setwd(paste0(path,"Research Project/IAT_Retest/Estimates/Lai2/"))
Lai21<-read.csv("IndividualParametersLaiStudy2PD1.csv", header = T)
Lai22<-read.csv("IndividualParametersLaiStudy2PD2.csv", header = T)

colnames(Lai21)[2:ncol(Lai21)]<-paste(colnames(Lai21[2:ncol(Lai21)]),"T1",sep="_")
colnames(Lai22)[2:ncol(Lai22)]<-paste(colnames(Lai22[2:ncol(Lai22)]),"T2",sep="_")

P.Lai2 <- merge(Lai21, Lai22, by = "session_id", all.x = T, all.y = T)

colnames(P.Cal)[1] <- "subID"
P.Cal <- cbind(P.Cal, Study = "Calanchini")
colnames(P.PI)[1] <- "subID"
P.PI <- cbind(P.PI, Study = "PI")
colnames(P.Gaw)[1] <- "subID"
P.Gaw <- cbind(P.Gaw, Study = "Gawronski")
colnames(P.For)[1] <- "subID"
P.For <- cbind(P.For, Study = "Forscher")
colnames(P.Lai1)[1] <- "subID"
P.Lai1 <- cbind(P.Lai1, Study = "Lai 1")
colnames(P.Lai2)[1] <- "subID"
P.Lai2 <- cbind(P.Lai2, Study = "Lai 2")

PD <- rbind(P.Cal,P.PI,P.Gaw,P.For,P.Lai1,P.Lai2)

PD$Study[PD$Study=="PI"]<-"Project Implicit, 2020"
PD$Study[PD$Study=="Calanchini"]<-"Wilson & Calanchini, 2022"
PD$Study[PD$Study=="Lai 1"]<-"Lai et al., 2016 (Study 1)  "
PD$Study[PD$Study=="Lai 2"]<-"Lai et al., 2016 (Study 2)  "
PD$Study[PD$Study=="Gawronski"]<-"Gawronski et al., 2017"
PD$Study[PD$Study=="Forscher"]<-"Forscher et al., 2017"

Quad Model

Associate Black-Bad

ACbbScatter <- ggplot(Quad, aes(x=ACbb1_T1, y=ACbb1_T2, color=Study)) + 
  geom_point(alpha = .2)+
  geom_smooth(method=lm, se=TRUE, linetype="dashed",
             color="grey")  + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Association Black-Bad",
       x="Time 1", y = "Time 2") + guides(colour = guide_legend(override.aes = list(alpha = 1))) +
  jtools::theme_apa() 
ACbbScatter
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"ACbbScatter.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"ACbbScatter.tiff"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'

Associate White-Good

ACwgScatter <- ggplot(Quad, aes(x=ACwg1_T1, y=ACwg1_T2, color=Study)) + 
  geom_point(alpha = .2)+
  geom_smooth(method=lm, se=TRUE, linetype="dashed",
             color="grey")  + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Association White-Good",
       x="Time 1", y = "Time 2") + guides(colour = guide_legend(override.aes = list(alpha = 1))) + theme(legend.title = element_text(size = 9)) +
  jtools::theme_apa()
ACwgScatter
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"ACwgScatter.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"ACwgScatter.tiff"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'

Detection

DScatter <- ggplot(Quad, aes(x=D1_T1, y=D1_T2, color=Study)) + 
  geom_point(alpha = .2)+
  geom_smooth(method=lm, se=TRUE, linetype="dashed",
             color="grey")  + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Detection",
       x="Time 1", y = "Time 2") + guides(colour = guide_legend(override.aes = list(alpha = 1))) + theme(legend.title = element_text(size = 9)) +
  jtools::theme_apa()
DScatter
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"DScatter.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"DScatter.tiff"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'

Overcoming Bias

OBScatter <- ggplot(Quad, aes(x=OB1_T1, y=OB1_T2, color=Study)) + 
  geom_point(alpha = .2)+
  geom_smooth(method=lm, se=TRUE, linetype="dashed",
             color="grey")  + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Overcoming Bias",
       x="Time 1", y = "Time 2") + guides(colour = guide_legend(override.aes = list(alpha = 1))) + theme(legend.title = element_text(size = 9))  +
  jtools::theme_apa()
OBScatter
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"OBScatter.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"OBScatter.tiff"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'

Guessing

GScatter <- ggplot(Quad, aes(x=G1_T1, y=G1_T2, color=Study)) + 
  geom_point(alpha = .2)+
  geom_smooth(method=lm, se=TRUE, linetype="dashed",
             color="grey")  + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Guessing",
       x="Time 1", y = "Time 2") + guides(colour = guide_legend(override.aes = list(alpha = 1))) +
  jtools::theme_apa()
ggsave(paste0(saveto,"GScatter.jpg"),dpi=600)
Saving 7 x 7 in image
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"GScatter.tiff"),dpi=600)
Saving 7 x 7 in image
`geom_smooth()` using formula 'y ~ x'

Panel

library(ggpubr)
QuadPanel1 <- ggarrange(ACwgScatter, ACbbScatter, DScatter, OBScatter, GScatter,
          ncol = 3, nrow = 2, common.legend = T)
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
QuadPanel1


require(grid)   # for the textGrob() function

QuadPanel2 <- ggarrange(ACwgScatter  + theme(plot.title = element_text(size=12)) + theme(legend.text = element_text(size = 8)) + rremove("ylab") + rremove("xlab"), 
                        ACbbScatter  + theme(plot.title = element_text(size=12)) + rremove("ylab") + rremove("xlab"),
                        DScatter  + theme(plot.title = element_text(size=12)) + rremove("ylab") + rremove("xlab"),
                        OBScatter  + theme(plot.title = element_text(size=12)) + rremove("ylab") + rremove("xlab"),
                        GScatter  + theme(plot.title = element_text(size=12)) + rremove("ylab") + rremove("xlab"),
          ncol = 3, nrow = 2, common.legend = T, labels = NULL, legend = "bottom",
          align = "hv", 
                    font.label = list(size = 10, color = "black", face = "bold", family = NULL, position = "top"))
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
QuadPanel2


annotate_figure(QuadPanel2, left = textGrob("Time 2", rot = 90, vjust = 1, hjust = 0, gp = gpar(cex = 1)),
                    bottom = textGrob("Time 1", vjust = -6.5, gp = gpar(cex = 1))) + theme(legend.position = c(0,-1))
ggsave(paste0(saveto,"QuadPanel.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
ggsave(paste0(saveto,"QuadPanel.tiff"),dpi=600)
Saving 7.29 x 4.51 in image

PD Model

Automatic Black

AbScatter <- ggplot(PD, aes(x=Ab1_T1, y=Ab1_T2, color=Study)) + 
  geom_point(alpha = .2)+
  geom_smooth(method=lm, se=TRUE, linetype="dashed",
             color="grey")  + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Automatic Black",
       x="Time 1", y = "Time 2") + guides(colour = guide_legend(override.aes = list(alpha = 1))) +
  jtools::theme_apa()
AbScatter
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"AbScatter.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"AbScatter.tiff"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'

Associate White

AwScatter <- ggplot(PD, aes(x=Aw1_T1, y=Aw1_T2, color=Study)) + 
  geom_point(alpha = .2)+
  geom_smooth(method=lm, se=TRUE, linetype="dashed",
             color="grey")  + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Automatic White",
       x="Time 1", y = "Time 2") + guides(colour = guide_legend(override.aes = list(alpha = 1))) +
  jtools::theme_apa()
AwScatter
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"AwScatter.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"AwScatter.tiff"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'

Control Good

CpScatter <- ggplot(PD, aes(x=Cp1_T1, y=Cp1_T2, color=Study)) + 
  geom_point(alpha = .2)+
  geom_smooth(method=lm, se=TRUE, linetype="dashed",
             color="grey")  + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Control Good",
       x="Time 1", y = "Time 2") + guides(colour = guide_legend(override.aes = list(alpha = 1))) +
  jtools::theme_apa()
CpScatter
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"CpScatter.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"CpScatter.tiff"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'

Control Bad

CuScatter <- ggplot(PD, aes(x=Cu1_T1, y=Cu1_T2, color=Study)) + 
  geom_point(alpha = .2)+
  geom_smooth(method=lm, se=TRUE, linetype="dashed",
             color="grey")  + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Control Bad",
       x="Time 1", y = "Time 2") + guides(colour = guide_legend(override.aes = list(alpha = 1))) +
  jtools::theme_apa()
CuScatter
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"CuScatter.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"CuScatter.tiff"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'

Control White

CwScatter <- ggplot(PD, aes(x=Cw1_T1, y=Cw1_T2, color=Study)) + 
  geom_point(alpha = .2)+
  geom_smooth(method=lm, se=TRUE, linetype="dashed",
             color="grey")  + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Control White",
       x="Time 1", y = "Time 2") + guides(colour = guide_legend(override.aes = list(alpha = 1))) +
  jtools::theme_apa()
CwScatter
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"CwScatter.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"CwScatter.tiff"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'

Control Black

CbScatter <- ggplot(PD, aes(x=Cb1_T1, y=Cb1_T2, color=Study)) + 
  geom_point(alpha = .2)+
  geom_smooth(method=lm, se=TRUE, linetype="dashed",
             color="grey")  + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Control Black",
       x="Time 1", y = "Time 2") + guides(colour = guide_legend(override.aes = list(alpha = 1))) +
  jtools::theme_apa()
CbScatter
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"CbScatter.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"CbScatter.tiff"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'

Panel

library(ggpubr)
PDPanel1 <- ggarrange(AwScatter, AbScatter, CuScatter, CpScatter, CbScatter, CwScatter,
          ncol = 3, nrow = 2, common.legend = T)
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
PDPanel1


require(grid)   # for the textGrob() function

PDPanel2 <- ggarrange(AwScatter  + theme(plot.title = element_text(size=12))  + theme(legend.text = element_text(size = 8)) + rremove("ylab") + rremove("xlab"), 
                        AbScatter  + theme(plot.title = element_text(size=12)) + rremove("ylab") + rremove("xlab"),
                        CuScatter  + theme(plot.title = element_text(size=12)) + rremove("ylab") + rremove("xlab"),
                        CpScatter  + theme(plot.title = element_text(size=12)) + rremove("ylab") + rremove("xlab"),
                        CbScatter  + theme(plot.title = element_text(size=12)) + rremove("ylab") + rremove("xlab"),
                        CwScatter  + theme(plot.title = element_text(size=12)) + rremove("ylab") + rremove("xlab"),
          ncol = 3, nrow = 2, common.legend = T, labels = NULL, legend = "bottom",
          align = "hv", 
                    font.label = list(size = 10, color = "black", face = "bold", family = NULL, position = "top"))
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
PDPanel2 <- annotate_figure(PDPanel2, left = textGrob("Time 2", rot = 90, vjust = 1, hjust = 0, gp = gpar(cex = 1)),
                    bottom = textGrob("Time 1", vjust = -6.5, gp = gpar(cex = 1))) + theme(legend.position = c(0,-1))
PDPanel2
ggsave(paste0(saveto,"PDPanel.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
ggsave(paste0(saveto,"PDPanel.tiff"),dpi=600)
Saving 7.29 x 4.51 in image

Reliability Meta-Analysis

dt <- read.csv("~/Documents/GitHub/MPT-Reliability/Retest/output/combQuad_Df.csv")[2:6]

dt$Param[dt$Param=="D"]<-"Detection"
dt$Param[dt$Param=="OB"]<-"Overcoming Bias"
dt$Param[dt$Param=="ACbb"]<-"Association Black-Bad"
dt$Param[dt$Param=="ACwg"]<-"Association White-Good"
dt$Param[dt$Param=="G"]<-"Guessing"

dt$Param[dt$Param=="PI"]<-"Project Implicit, 2020"
dt$Param[dt$Param=="Calanchini"]<-"Wilson & Calanchini, 2022"
dt$Param[dt$Param=="Lai1"]<-"Lai et al., 2016 (Study 1)  "
dt$Param[dt$Param=="Lai2"]<-"Lai et al., 2016 (Study 2)  "
dt$Param[dt$Param=="Gawronski"]<-"Gawronski et al., 2017"
dt$Param[dt$Param=="Forscher"]<-"Forscher et al., 2017"

# indent the subgroup if there is a number in the placebo column
dt$Param <- ifelse(dt$type==0, 
                      dt$Param,
                      paste0(" ", dt$Param))

colnames(dt)[colnames(dt)=="Param"] <- "   "
dt$` ` <- paste(rep(" ", 20), collapse = " ")
dt$`ICC (95% CI)` <- ifelse(is.na(dt$ICC), "",
                             sprintf("%.2f [%.2f, %.2f]",
                                     dt$ICC, dt$CI.LB, dt$CI.UB))


dt$ICCstudy <- ifelse(dt$type==1, dt$ICC, NA)
dt$ICC.LBstudy <- ifelse(dt$type==1, dt$CI.LB, NA)
dt$ICC.UBstudy <- ifelse(dt$type==1, dt$CI.UB, NA)
dt$Sizestudy <- ifelse(dt$type==1, .6, NA)
dt$Sizemeta <- ifelse(dt$type==0, 1.2, NA)
dt$ICCmeta <- ifelse(dt$type==0, dt$ICC, NA)
dt$ICC.LBmeta <- ifelse(dt$type==0, dt$CI.LB, NA)
dt$ICC.UBmeta <- ifelse(dt$type==0, dt$CI.UB, NA)

#dt<-dt[c(1:4,6:7)]
dt<-dt[c(1:4,6:ncol(dt))]
colnames(dt)[colnames(dt)=="ICC (95% CI)"] <- "     "

library(forestploter)
# p <- forest(
#   dt[c(1,5,6)],
#             est = dt$ICC,
#             lower = dt$CI.LB, 
#             upper = dt$CI.UB,
#             ci_column = 2,
#             ref_line = .4,
#             xlim = c(-.1, 1),
#             ticks_at = c(0, .4,.6, .75, 1),
#   sizes = .1
# )

tm <- forest_theme(
                   ci_pch = c(15, 16),
                   ci_col = c("black","red"),
                   ci_lty = c( "solid", "dashed"),
                  # footnote_col = "blue",
                   legend_name = " ",
                  legend_position = "bottom",
                   legend_value = c("Meta-Analysis ", "Study")
                  
                  )

p <- forest(
  dt[c(1,5,6)],
            est = list(dt$ICCmeta, dt$ICCstudy),
            lower = list(dt$ICC.LBmeta, dt$ICC.LBstudy), 
            upper = list(dt$ICC.UBmeta, dt$ICC.UBstudy),
              ci_column = 2,
            ref_line = .4,
            xlim = c(-.1, 1),
            ticks_at = c(0, .4,.6, .75, 1),
  sizes = list(dt$Sizemeta, dt$Sizestudy),
  theme = tm
)

library(grid)
p <- edit_plot(p,
               row = seq(from=1,to=nrow(dt),by=7),
               gp = gpar(fontface = c("bold","italic")
                         ), col = 1)

studyInds <- setdiff(1:nrow(dt),seq(from=1,to=nrow(dt),by=7))
paramInds <- seq(from=1,to=nrow(dt),by=7)

p <- edit_plot(p, row = studyInds, which = "background",
               gp = gpar(fill = "white"))
p <- edit_plot(p, row = paramInds, which = "background",
               gp = gpar(fill = "grey"))
png(paste0(saveto,"Quad_TRT.png"), units="in", width=10, height=12, res=300)
plot(p)
dev.off()
null device 
          1 
# ggsave function
ggplot2::ggsave(paste0(saveto,"Quad_TRT.png"),
                dpi = 300,
                width = 6, height = 11, units = "in", plot=p)

ggplot2::ggsave(paste0(saveto,"Quad_TRT.tiff"),
                dpi = 600,
                width = 6, height = 11, units = "in", plot=p)
dt <- read.csv("~/Documents/GitHub/MPT-Reliability/Retest/output/combPD_Df.csv")[2:6]

dt$Param[dt$Param=="Ab"]<-"Automatic Black"
dt$Param[dt$Param=="Aw"]<-"Automatic White"
dt$Param[dt$Param=="Cb"]<-"Control Black"
dt$Param[dt$Param=="Cw"]<-"Control White"
dt$Param[dt$Param=="Cu"]<-"Control Bad"
dt$Param[dt$Param=="Cp"]<-"Control Good"

dt$Param[dt$Param=="PI"]<-"Project Implicit, 2020"
dt$Param[dt$Param=="Calanchini"]<-"Wilson & Calanchini, 2022"
dt$Param[dt$Param=="Lai1"]<-"Lai et al., 2016 (Study 1)  "
dt$Param[dt$Param=="Lai2"]<-"Lai et al., 2016 (Study 2)  "
dt$Param[dt$Param=="Gawronski"]<-"Gawronski et al., 2017"
dt$Param[dt$Param=="Forscher"]<-"Forscher et al., 2017"

# indent the subgroup if there is a number in the placebo column
dt$Param <- ifelse(dt$type==0, 
                      dt$Param,
                      paste0(" ", dt$Param))

colnames(dt)[colnames(dt)=="Param"] <- "   "
colnames(dt)[colnames(dt)=="Param"] <- "   "
dt$` ` <- paste(rep(" ", 20), collapse = " ")
dt$`ICC (95% CI)` <- ifelse(is.na(dt$ICC), "",
                             sprintf("%.2f [%.2f, %.2f]",
                                     dt$ICC, dt$CI.LB, dt$CI.UB))

dt$ICCstudy <- ifelse(dt$type==1, dt$ICC, NA)
dt$ICC.LBstudy <- ifelse(dt$type==1, dt$CI.LB, NA)
dt$ICC.UBstudy <- ifelse(dt$type==1, dt$CI.UB, NA)
dt$Sizestudy <- ifelse(dt$type==1, .6, NA)
dt$Sizemeta <- ifelse(dt$type==0, 1.2, NA)
dt$ICCmeta <- ifelse(dt$type==0, dt$ICC, NA)
dt$ICC.LBmeta <- ifelse(dt$type==0, dt$CI.LB, NA)
dt$ICC.UBmeta <- ifelse(dt$type==0, dt$CI.UB, NA)

#dt<-dt[c(1:4,6:7)]
dt<-dt[c(1:4,6:ncol(dt))]
colnames(dt)[colnames(dt)=="ICC (95% CI)"] <- "     "

library(forestploter)
# p <- forest(
#   dt[c(1,5,6)],
#             est = dt$ICC,
#             lower = dt$CI.LB, 
#             upper = dt$CI.UB,
#             ci_column = 2,
#             ref_line = .4,
#             xlim = c(-.1, 1),
#             ticks_at = c(0, .4,.6, .75, 1),
#   sizes = .1
# )

tm <- forest_theme(
                   ci_pch = c(15, 16),
                   ci_col = c("black","red"),
                   ci_lty = c( "solid", "dashed"),
                  # footnote_col = "blue",
                   legend_name = " ",
                  legend_position = "bottom",
                   legend_value = c("Meta-Analysis ", "Study")
                  
                  )

p <- forest(
  dt[c(1,5,6)],
            est = list(dt$ICCmeta, dt$ICCstudy),
            lower = list(dt$ICC.LBmeta, dt$ICC.LBstudy), 
            upper = list(dt$ICC.UBmeta, dt$ICC.UBstudy),
              ci_column = 2,
            ref_line = .4,
            xlim = c(-.1, 1),
            ticks_at = c(0, .4,.6, .75, 1),
  sizes = list(dt$Sizemeta, dt$Sizestudy),
  theme = tm
)

library(grid)
p <- edit_plot(p,
               row = seq(from=1,to=nrow(dt),by=7),
               gp = gpar(fontface = c("bold","italic")
                         ), col = 1)

studyInds <- setdiff(1:nrow(dt),seq(from=1,to=nrow(dt),by=7))
paramInds <- seq(from=1,to=nrow(dt),by=7)

p <- edit_plot(p, row = studyInds, which = "background",
               gp = gpar(fill = "white"))
p <- edit_plot(p, row = paramInds, which = "background",
               gp = gpar(fill = "grey"))
png(paste0(saveto,"PDP_TRT.png"), units="in", width=10, height=15, res=300)
plot(p)
dev.off()
null device 
          1 
# ggsave function
ggplot2::ggsave(paste0(saveto,"PDP_TRT.png"),
                dpi = 300,
                width = 6, height = 13, units = "in", plot=p)

ggplot2::ggsave(paste0(saveto,"PDP_TRT.tiff"),
                dpi = 600,
                width = 6, height = 13, units = "in", plot=p)

Recovery

setwd(paste0("/Volumes/Research Project/IAT_Retest/Recovery/RecoveredParams/PD/"))
Warning: The working directory was changed to /Volumes/Research Project/IAT_Retest/Recovery/RecoveredParams/PD inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
times<-c("Time1","Time2")

allrecovs <- as.data.frame(matrix(ncol=14,nrow=0))

PDdirs <- list.dirs(path = ".", full.names = TRUE, recursive = TRUE)[-1]
for(d in PDdirs){
  for(ti in times){
    curFiles <- list.files(path=d,pattern="\\.csv$")
    id<-grep(ti,curFiles)
    output<-read.csv(paste0(d,"/",curFiles[id]))
    name<-gsub("./","",d)
    name<-gsub(" ","",name)
    
    if(ti=="Time1"){
      #colnames(output) <- paste(colnames(output),"T1",sep="_")
      output$time <- "T1"
    }else if(ti=="Time2"){
      #colnames(output) <- paste(colnames(output),"T2",sep="_")
      output$time <- "T2"
    }
    
    assign(paste0(name,".PD.Recov.",ti),output)
  }
  df <- rbind(get(paste0(name,".PD.Recov.Time1")),get(paste0(name,".PD.Recov.Time2")))
  assign(paste0(name,".PD.Recov"),df)
  allrecovs <- rbind(allrecovs,cbind(df,Study=name))
}


allrecovs$Study <- gsub("Lai1", "Lai 1", allrecovs$Study)
allrecovs$Study <- gsub("Lai2", "Lai 2", allrecovs$Study)
PD.recovs <- allrecovs
PD.recovs <- dplyr::rename(PD.recovs, subID=X)

tapply(PD.recovs$Ab1, PD.recovs$Study, function(x) length(x))
Calanchini   Forscher  Gawronski      Lai 1      Lai 2         PI 
       210         64        232        160        926       2480 
path <- "/Volumes/"
setwd(paste0(path,"Research Project/IAT_Retest/Estimates/UCR/"))
Warning: The working directory was changed to /Volumes/Research Project/IAT_Retest/Estimates/UCR inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
Cal1 <-read.csv("IndividualParametersPDUCR1.csv", header = T)
Cal2 <-read.csv("IndividualParametersPDUCR2.csv", header = T)

Cal1$time <- "T1"
Cal2$time <- "T2"
Cal1$subID <- 1:nrow(Cal1)
Cal2$subID <- 1:nrow(Cal2)
P.Cal <- rbind(Cal1, Cal2)

setwd(paste0(path,"Research Project/IAT_Retest/Estimates/PI/"))
PI1 <- read.csv("IndividualParametersProjectImplicitPD1.csv")
PI2 <- read.csv("IndividualParametersProjectImplicitPD2.csv")

PI1$time <- "T1"
PI2$time <- "T2"
PI1$subID <- 1:nrow(PI1)
PI2$subID <- 1:nrow(PI2)
P.PI <- rbind(PI1, PI2)

setwd(paste0(path,"Research Project/IAT_Retest/Estimates/Gawronski/"))
Gaw1 <- read.csv("IndividualParametersPDGawronski1.csv")
Gaw2 <- read.csv("IndividualParametersPDGawronski2.csv")

Gaw1$time <- "T1"
Gaw2$time <- "T2"
Gaw1$subID <- 1:nrow(Gaw1)
Gaw2$subID <- 1:nrow(Gaw2)
P.Gaw <- rbind(Gaw1, Gaw2)

setwd(paste0(path,"Research Project/IAT_Retest/Estimates/Forscher/"))
For1<-read.csv("IndividualParametersForscherPD1.csv", header = T)
For2<-read.csv("IndividualParametersForscherPD2.csv", header = T)

For1$time <- "T1"
For2$time <- "T2"
For1$subID <- 1:nrow(For1)
For2$subID <- 1:nrow(For2)
P.For <- rbind(For1, For2)

setwd(paste0(path,"Research Project/IAT_Retest/Estimates/Lai1/"))
Lai11<-read.csv("IndividualParametersLaiStudy1PD1.csv", header = T)
Lai12<-read.csv("IndividualParametersLaiStudy1PD2.csv", header = T)

Lai11$time <- "T1"
Lai12$time <- "T2"
Lai11$subID <- 1:nrow(Lai11)
Lai12$subID <- 1:nrow(Lai12)
P.Lai1 <- rbind(Lai11, Lai12)

setwd(paste0(path,"Research Project/IAT_Retest/Estimates/Lai2/"))
Lai21<-read.csv("IndividualParametersLaiStudy2PD1.csv", header = T)
Lai22<-read.csv("IndividualParametersLaiStudy2PD2.csv", header = T)

Lai21$time <- "T1"
Lai22$time <- "T2"
Lai21$subID <- 1:nrow(Lai21)
Lai22$subID <- 1:nrow(Lai22)
P.Lai2 <- rbind(Lai21,Lai22)

colnames(P.Cal)[1] <- "subID"
P.Cal <- cbind(P.Cal, Study = "Calanchini")
colnames(P.PI)[1] <- "subID"
P.PI <- cbind(P.PI, Study = "PI")
colnames(P.Gaw)[1] <- "subID"
P.Gaw <- cbind(P.Gaw, Study = "Gawronski")
colnames(P.For)[1] <- "subID"
P.For <- cbind(P.For, Study = "Forscher")
colnames(P.Lai1)[1] <- "subID"
P.Lai1 <- cbind(P.Lai1, Study = "Lai 1")
colnames(P.Lai2)[1] <- "subID"
P.Lai2 <- cbind(P.Lai2, Study = "Lai 2")

PD.orig <- rbind(P.Cal,P.PI,P.Gaw,P.For,P.Lai1,P.Lai2)
PD.orig[1] <- NULL

colnames(PD.recovs)[2: (ncol(PD.recovs)-2) ] <- paste(colnames(PD.recovs)[2: (ncol(PD.recovs)-2) ],"R",sep="_")
colnames(PD.orig)[1: (ncol(PD.orig)-3) ] <- paste(colnames(PD.orig)[1: (ncol(PD.orig)-3) ],"O",sep="_")
PD.orig <- PD.orig[order(PD.orig$Study, PD.orig$time),]
PD.recovs <- PD.recovs[order(PD.recovs$Study, PD.recovs$time),]

#PD.orig.recovs <- cbind(PD.orig,PD.recovs)
PD.orig.recovs <- merge(PD.orig, PD.recovs, by = c("subID","Study","time"))

PD.orig.recovs$Study[PD.orig.recovs$Study=="PI"]<-"Project Implicit, 2020"
PD.orig.recovs$Study[PD.orig.recovs$Study=="Calanchini"]<-"Wilson & Calanchini, 2022"
PD.orig.recovs$Study[PD.orig.recovs$Study=="Lai 1"]<-"Lai et al., 2016 (Study 1)  "
PD.orig.recovs$Study[PD.orig.recovs$Study=="Lai 2"]<-"Lai et al., 2016 (Study 2)  "
PD.orig.recovs$Study[PD.orig.recovs$Study=="Gawronski"]<-"Gawronski et al., 2017"
PD.orig.recovs$Study[PD.orig.recovs$Study=="Forscher"]<-"Forscher et al., 2017"

Recovery

PD Model

Automatic Black

AbScatter <- ggplot(PD.orig.recovs, aes(x=Ab1_O, y=Ab1_R, color=Study, shape=time)) + 
  geom_point(alpha = .2)+
  geom_smooth(method=lm, se=TRUE, linetype = "dashed",
             color="grey")  + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Automatic Black",
       x="Original", y = "Recovered") + guides(colour = guide_legend(override.aes = list(alpha = 1))) +
  jtools::theme_apa()

AbScatter
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"AbScatterREC.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"AbScatterREC.tiff"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'

Automatic White

AwScatter <- ggplot(PD.orig.recovs, aes(x=Aw1_O, y=Aw1_R, color=Study, shape=time)) + 
  geom_point(alpha = .2)+
  geom_smooth(method=lm, se=TRUE, linetype="dashed",
             color="grey")  + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Automatic White",
       x="Original", y = "Recovered") + guides(colour = guide_legend(override.aes = list(alpha = 1))) +
  jtools::theme_apa()
AwScatter
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"AwScatterREC.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"AwScatterREC.tiff"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'

Control Good

CpScatter <- ggplot(PD.orig.recovs, aes(x=Cp1_O, y=Cp1_R, color=Study, shape=time)) + 
  geom_point(alpha = .2)+
  geom_smooth(method=lm, se=TRUE, linetype="dashed",
             color="grey")  + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Control Good",
       x="Original", y = "Recovered") + guides(colour = guide_legend(override.aes = list(alpha = 1))) +
  jtools::theme_apa()
CpScatter
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"CpScatterREC.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"AwScatterREC.tiff"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'

Control Bad

CuScatter <- ggplot(PD.orig.recovs, aes(x=Cu1_O, y=Cu1_R, color=Study, shape=time)) + 
  geom_point(alpha = .2)+
  geom_smooth(method=lm, se=TRUE, linetype="dashed",
             color="grey")  + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Control Bad",
       x="Original", y = "Recovered") + guides(colour = guide_legend(override.aes = list(alpha = 1))) +
  jtools::theme_apa()
CuScatter
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"CuScatterREC.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"CuScatterREC.tiff"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'

Control White

CwScatter <- ggplot(PD.orig.recovs, aes(x=Cw1_O, y=Cw1_R, color=Study, shape=time)) + 
  geom_point(alpha = .2)+
  geom_smooth(method=lm, se=TRUE, linetype="dashed",
             color="grey")  + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Control White",
       x="Original", y = "Recovered") + guides(colour = guide_legend(override.aes = list(alpha = 1))) +
  jtools::theme_apa()
CwScatter
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"CwScatterREC.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"CwScatterREC.tiff"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'

Control Black

CbScatter <- ggplot(PD.orig.recovs, aes(x=Cb1_O, y=Cb1_R, color=Study, shape=time)) + 
  geom_point(alpha = .2)+
  geom_smooth(method=lm, se=TRUE, linetype="dashed",
             color="grey")  + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Control Black",
       x="Original", y = "Recovered") + guides(colour = guide_legend(override.aes = list(alpha = 1))) +
  jtools::theme_apa()
CbScatter
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"CbScatterREC.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"CbScatterREC.tiff"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'

Panel

library(ggpubr)
PDPanel1 <- ggarrange(AwScatter, AbScatter, CuScatter, CpScatter, CbScatter, CwScatter,
          ncol = 3, nrow = 2, common.legend = T)
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
PDPanel1


require(grid)   # for the textGrob() function

PDPanel2 <- ggarrange(AwScatter  + theme(plot.title = element_text(size=12)) + theme(legend.text = element_text(size = 8)) + rremove("ylab") + rremove("xlab"), 
                        AbScatter  + theme(plot.title = element_text(size=12)) + rremove("ylab") + rremove("xlab"),
                        CuScatter  + theme(plot.title = element_text(size=12)) + rremove("ylab") + rremove("xlab"),
                        CpScatter  + theme(plot.title = element_text(size=12)) + rremove("ylab") + rremove("xlab"),
                        CbScatter  + theme(plot.title = element_text(size=12)) + rremove("ylab") + rremove("xlab"),
                        CwScatter  + theme(plot.title = element_text(size=12)) + rremove("ylab") + rremove("xlab"),
          ncol = 3, nrow = 2, common.legend = T, labels = NULL, legend = c("bottom"),
          align = "hv", 
                    font.label = list(size = 10, color = "black", face = "bold", family = NULL, position = "top"))
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
PDPanel2 <- annotate_figure(PDPanel2, left = textGrob("Recovered", rot = 90, vjust = 1, hjust = 0, gp = gpar(cex = 1)),
                    bottom = textGrob("Original", vjust = -6.5, gp = gpar(cex = 1))) + theme(legend.position = c(0,-1))
PDPanel2
ggsave(paste0(saveto,"PDPanelREC.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
ggsave(paste0(saveto,"PDPanelREC.tiff"),dpi=600)
Saving 7.29 x 4.51 in image

Quad Model

Recovery

setwd(paste0("/Volumes/Research Project/IAT_Retest/Recovery/RecoveredParams/Quad/"))
Warning: The working directory was changed to /Volumes/Research Project/IAT_Retest/Recovery/RecoveredParams/Quad inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
times<-c("Time1","Time2")

allrecovs <- as.data.frame(matrix(ncol=14,nrow=0))

Quaddirs <- list.dirs(path = ".", full.names = TRUE, recursive = TRUE)[-1]
for(d in Quaddirs){
  for(ti in times){
    curFiles <- list.files(path=d,pattern="\\.csv$")
    id<-grep(ti,curFiles)
    output<-read.csv(paste0(d,"/",curFiles[id]))
    name<-gsub("./","",d)
    name<-gsub(" ","",name)
    
    if(ti=="Time1"){
      #colnames(output) <- paste(colnames(output),"T1",sep="_")
      output$time <- "T1"
    }else if(ti=="Time2"){
      #colnames(output) <- paste(colnames(output),"T2",sep="_")
      output$time <- "T2"
    }
    
    assign(paste0(name,".Quad.Recov.",ti),output)
  }
  df <- rbind(get(paste0(name,".Quad.Recov.Time1")),get(paste0(name,".Quad.Recov.Time2")))
  assign(paste0(name,".Quad.Recov"),df)
  allrecovs <- rbind(allrecovs,cbind(df,Study=name))
}


allrecovs$Study <- gsub("Lai1", "Lai 1", allrecovs$Study)
allrecovs$Study <- gsub("Lai2", "Lai 2", allrecovs$Study)
Quad.recovs <- allrecovs
Quad.recovs <- dplyr::rename(Quad.recovs, subID=X)

tapply(Quad.recovs$ACbb1, Quad.recovs$Study, function(x) length(x))
Calanchini   Forscher  Gawronski      Lai 1      Lai 2         PI 
       210         64        232        160        926       2480 
path <- "/Volumes/"
setwd(paste0(path,"Research Project/IAT_Retest/Estimates/UCR/"))
Warning: The working directory was changed to /Volumes/Research Project/IAT_Retest/Estimates/UCR inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
Cal1 <-read.csv("IndividualParametersQuadUCR1.csv", header = T)
Cal2 <-read.csv("IndividualParametersQuadUCR2.csv", header = T)

Cal1$time <- "T1"
Cal2$time <- "T2"
Cal1$subID <- 1:nrow(Cal1)
Cal2$subID <- 1:nrow(Cal2)
P.Cal <- rbind(Cal1, Cal2)

setwd(paste0(path,"Research Project/IAT_Retest/Estimates/PI/"))
PI1 <- read.csv("IndividualParametersQuadProjectImplicit1.csv")
PI2 <- read.csv("IndividualParametersQuadProjectImplicit2.csv")

PI1$time <- "T1"
PI2$time <- "T2"
PI1$subID <- 1:nrow(PI1)
PI2$subID <- 1:nrow(PI2)
P.PI <- rbind(PI1, PI2)

setwd(paste0(path,"Research Project/IAT_Retest/Estimates/Gawronski/"))
Gaw1 <- read.csv("IndividualParametersQuadGawronski1.csv")
Gaw2 <- read.csv("IndividualParametersQuadGawronski2.csv")

Gaw1$time <- "T1"
Gaw2$time <- "T2"
Gaw1$subID <- 1:nrow(Gaw1)
Gaw2$subID <- 1:nrow(Gaw2)
P.Gaw <- rbind(Gaw1, Gaw2)

setwd(paste0(path,"Research Project/IAT_Retest/Estimates/Forscher/"))
For1<-read.csv("IndividualParametersQuadForscher1.csv", header = T)
For2<-read.csv("IndividualParametersQuadForscher2.csv", header = T)

For1$time <- "T1"
For2$time <- "T2"
For1$subID <- 1:nrow(For1)
For2$subID <- 1:nrow(For2)
P.For <- rbind(For1, For2)

setwd(paste0(path,"Research Project/IAT_Retest/Estimates/Lai1/"))
Lai11<-read.csv("IndividualParametersLaiStudy1Quad1.csv", header = T)
Lai12<-read.csv("IndividualParametersLaiStudy1Quad2.csv", header = T)

Lai11$time <- "T1"
Lai12$time <- "T2"
Lai11$subID <- 1:nrow(Lai11)
Lai12$subID <- 1:nrow(Lai12)
P.Lai1 <- rbind(Lai11, Lai12)

setwd(paste0(path,"Research Project/IAT_Retest/Estimates/Lai2/"))
Lai21<-read.csv("IndividualParametersLaiStudy2Quad1.csv", header = T)
Lai22<-read.csv("IndividualParametersLaiStudy2Quad2.csv", header = T)

Lai21$time <- "T1"
Lai22$time <- "T2"
Lai21$subID <- 1:nrow(Lai21)
Lai22$subID <- 1:nrow(Lai22)
P.Lai2 <- rbind(Lai21,Lai22)

colnames(P.Cal)[1] <- "subID"
P.Cal <- cbind(P.Cal, Study = "Calanchini")
colnames(P.PI)[1] <- "subID"
P.PI <- cbind(P.PI, Study = "PI")
colnames(P.Gaw)[1] <- "subID"
P.Gaw <- cbind(P.Gaw, Study = "Gawronski")
colnames(P.For)[1] <- "subID"
P.For <- cbind(P.For, Study = "Forscher")
colnames(P.Lai1)[1] <- "subID"
P.Lai1 <- cbind(P.Lai1, Study = "Lai 1")
colnames(P.Lai2)[1] <- "subID"
P.Lai2 <- cbind(P.Lai2, Study = "Lai 2")

Quad.orig <- rbind(P.Cal,P.PI,P.Gaw,P.For,P.Lai1,P.Lai2)
Quad.orig[1] <- NULL
colnames(Quad.recovs)[2: (ncol(Quad.recovs)-2) ] <- paste(colnames(Quad.recovs)[2: (ncol(Quad.recovs)-2) ],"R",sep="_")
colnames(Quad.orig)[1: (ncol(Quad.orig)-3) ] <- paste(colnames(Quad.orig)[1: (ncol(Quad.orig)-3) ],"O",sep="_")
Quad.orig <- Quad.orig[order(Quad.orig$Study, Quad.orig$time),]
Quad.recovs <- Quad.recovs[order(Quad.recovs$Study, Quad.recovs$time),]

#Quad.orig.recovs <- cbind(Quad.orig,Quad.recovs)
Quad.orig.recovs <- merge(Quad.orig, Quad.recovs, by = c("subID","Study","time"))

Quad.orig.recovs$Study[Quad.orig.recovs$Study=="PI"]<-"Project Implicit, 2020"
Quad.orig.recovs$Study[Quad.orig.recovs$Study=="Calanchini"]<-"Wilson & Calanchini, 2022"
Quad.orig.recovs$Study[Quad.orig.recovs$Study=="Lai 1"]<-"Lai et al., 2016 (Study 1)  "
Quad.orig.recovs$Study[Quad.orig.recovs$Study=="Lai 2"]<-"Lai et al., 2016 (Study 2)  "
Quad.orig.recovs$Study[Quad.orig.recovs$Study=="Gawronski"]<-"Gawronski et al., 2017"
Quad.orig.recovs$Study[Quad.orig.recovs$Study=="Forscher"]<-"Forscher et al., 2017"

Quad Model

Associate Black-Bad

ACbbScatter <- ggplot(Quad.orig.recovs, aes(x=ACbb1_O, y=ACbb1_R, color=Study, shape=time)) + 
  geom_point(alpha = .2)+
  geom_smooth(method=lm, se=TRUE, linetype="dashed",
             color="grey")  + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Association Black-Bad",
       x="Original", y = "Recovered") + guides(colour = guide_legend(override.aes = list(alpha = 1))) +
  jtools::theme_apa()
ACbbScatter
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"ACbbScatterREC.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"ACbbScatterREC.tiff"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'

Associate White-Good

ACwgScatter <- ggplot(Quad.orig.recovs, aes(x=ACwg1_O, y=ACwg1_R, color=Study, shape=time)) + 
  geom_point(alpha = .2)+
  geom_smooth(method=lm, se=TRUE, linetype="dashed",
             color="grey")  + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Association White-Good",
       x="Original", y = "Recovered") + guides(colour = guide_legend(override.aes = list(alpha = 1))) +
  jtools::theme_apa()
ACwgScatter
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"ACwgScatterREC.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"ACwgScatterREC.tiff"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'

Detection

DScatter <- ggplot(Quad.orig.recovs, aes(x=D1_O, y=D1_R, color=Study, shape=time)) + 
  geom_point(alpha = .2)+
  geom_smooth(method=lm, se=TRUE, linetype="dashed",
             color="grey")  + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Detection",
       x="Original", y = "Recovered") + guides(colour = guide_legend(override.aes = list(alpha = 1))) +
  jtools::theme_apa()
DScatter
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"DScatterREC.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"DScatterREC.tiff"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'

Overcoming Bias

OBScatter <- ggplot(Quad.orig.recovs, aes(x=OB1_O, y=OB1_R, color=Study, shape=time)) + 
  geom_point(alpha = .2)+
  geom_smooth(method=lm, se=TRUE, linetype="dashed",
             color="grey")  + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Overcoming Bias",
       x="Original", y = "Recovered") + guides(colour = guide_legend(override.aes = list(alpha = 1))) +
  jtools::theme_apa()
OBScatter
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"OBScatterREC.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"OBScatterREC.tiff"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'

Guessing

GScatter <- ggplot(Quad.orig.recovs, aes(x=G1_O, y=G1_R, color=Study, shape=time)) + 
  geom_point(alpha = .2)+
  geom_smooth(method=lm, se=TRUE, linetype="dashed",
             color="grey")  + geom_abline(intercept = 0, slope = 1) + ylim(0,1) + xlim(0,1) + labs(title="Guessing",
       x="Original", y = "Recovered") + guides(colour = guide_legend(override.aes = list(alpha = 1))) +
  jtools::theme_apa()
GScatter
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"GScatter.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'
ggsave(paste0(saveto,"GScatter.tiff"),dpi=600)
Saving 7.29 x 4.51 in image
`geom_smooth()` using formula 'y ~ x'

Panel

library(ggpubr)
QuadPanel1 <- ggarrange(ACwgScatter, ACbbScatter, DScatter, OBScatter, GScatter,
          ncol = 3, nrow = 2, common.legend = T)
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
QuadPanel1


require(grid)   # for the textGrob() function

QuadPanel2 <- ggarrange(ACwgScatter  + theme(plot.title = element_text(size=12))  + theme(legend.text = element_text(size = 8)) + rremove("ylab") + rremove("xlab"), 
                        ACbbScatter  + theme(plot.title = element_text(size=12)) + rremove("ylab") + rremove("xlab"),
                        DScatter  + theme(plot.title = element_text(size=12)) + rremove("ylab") + rremove("xlab"),
                        OBScatter  + theme(plot.title = element_text(size=12)) + rremove("ylab") + rremove("xlab"),
                        GScatter  + theme(plot.title = element_text(size=12)) + rremove("ylab") + rremove("xlab"),
          ncol = 3, nrow = 2, common.legend = T, labels = NULL, legend = "bottom",
          align = "hv", 
                    font.label = list(size = 10, color = "black", face = "bold", family = NULL, position = "top"))
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
QuadPanel2


annotate_figure(QuadPanel2, left = textGrob("Recovered", rot = 90, vjust = 1, hjust = 0, gp = gpar(cex = 1)),
                    bottom = textGrob("Original", vjust = -6.5, gp = gpar(cex = 1))) + theme(legend.position = c(0,-1))
ggsave(paste0(saveto,"QuadPanelREC.jpg"),dpi=600)
Saving 7.29 x 4.51 in image
ggsave(paste0(saveto,"QuadPanelREC.tiff"),dpi=600)
Saving 7.29 x 4.51 in image

Recovery Meta-Analysis

Quad

dt <- read.csv("~/Documents/GitHub/MPT-Reliability/Recovery/output/combQuad_Recovery_Df.csv")[2:7]
dt$id <- unlist(lapply(1:5, function(x) rep(x,times=13)))

dt$Param[dt$Param=="D"]<-"Detection"
dt$Param[dt$Param=="OB"]<-"Overcoming Bias"
dt$Param[dt$Param=="ACbb"]<-"Association Black-Bad"
dt$Param[dt$Param=="ACwg"]<-"Association White-Good"
dt$Param[dt$Param=="G"]<-"Guessing"

dt$Param[dt$Param=="PI"]<-"Project Implicit, 2020"
dt$Param[dt$Param=="Calanchini"]<-"Wilson & Calanchini, 2022"
dt$Param[dt$Param=="Lai1"]<-"Lai et al., 2016 (Study 1)  "
dt$Param[dt$Param=="Lai2"]<-"Lai et al., 2016 (Study 2)  "
dt$Param[dt$Param=="Gawronski"]<-"Gawronski et al., 2017"
dt$Param[dt$Param=="Forscher"]<-"Forscher et al., 2017"

# indent the subgroup if there is a number in the placebo column
dt$Param <- ifelse(dt$type==0, 
                      dt$Param,
                      paste0(" ", dt$Param))

dt$` ` <- paste(rep(" ", 20), collapse = " ")
dt$`Recovery (95% CI)` <- ifelse(is.na(dt$Recov), "",
                             sprintf("%.2f [%.2f, %.2f]",
                                     dt$Recov, dt$CI.LB, dt$CI.UB))

dt2 <- pivot_wider(dt, id_cols = c("Param","id"),  names_from = c(Time), values_from = c(Recov,CI.LB,CI.UB,`Recovery (95% CI)`) )
dt2$`Recovery [95% CI]` <- ifelse(!is.na(dt2$`Recovery (95% CI)_Meta`), paste0("                 ",dt2$`Recovery (95% CI)_Meta`), paste0("T1 :", paste0(dt2$`Recovery (95% CI)_Time1`), " ; ", "T2: ", paste0(dt2$`Recovery (95% CI)_Time2`)))
dt2$` ` <- paste(rep(" ", 20), collapse = " ")


dt3<-dt2 %>% select(Param,Recov_Meta:11,15,16)

colnames(dt3)[colnames(dt3)=="Param"] <- "   "
colnames(dt3)[colnames(dt3)=="Recovery [95% CI]"] <- "    "

dt3$size_Meta <- ifelse(is.na(dt3$Recov_Meta), NA, 1.2)
dt3$size_T1 <- ifelse(is.na(dt3$Recov_Time1), NA, .6)
dt3$size_T2 <- ifelse(is.na(dt3$Recov_Time2), NA, .6)

# Set-up theme
tm <- forest_theme(
                   ci_pch = c(15, 16, 17),
                   ci_col = c("black","red","blue"),
                   ci_lty = c( "solid", "dashed", "dotted"),
                  # footnote_col = "blue",
                   legend_name = " ",
                  legend_position = "bottom",
                   legend_value = c("Meta-Analysis ", "Time 1 ", "Time 2 "))

library(forestploter)
p <- forest(
  dt3[c(1,12,11)],
            est = list(dt3$Recov_Meta, dt3$Recov_Time1, dt3$Recov_Time2),
            lower = list(dt3$CI.LB_Meta, dt3$CI.LB_Time1, dt3$CI.LB_Time2), 
            upper = list(dt3$CI.UB_Meta, dt3$CI.UB_Time1, dt3$CI.UB_Time2),
            ci_column = 2,
            ref_line = .7,
            xlim = c(-.1, 1),
            ticks_at = c(0, .2, .5, .7, 1),
  sizes = list(dt3$size_Meta, dt3$size_T1, dt3$size_T2),
  theme = tm
)
plot(p)


library(grid)
p <- edit_plot(p,
               row = seq(from=1,to=nrow(dt3),by=7),
               gp = gpar(fontface = c("bold","italic")
                         ), col = 1)

studyInds <- setdiff(1:nrow(dt3),seq(from=1,to=nrow(dt3),by=7))
paramInds <- seq(from=1,to=nrow(dt),by=7)

p <- edit_plot(p, row = studyInds, which = "background",
               gp = gpar(fill = "white"))
p <- edit_plot(p, row = paramInds, which = "background",
               gp = gpar(fill = "grey"))
png("~/Desktop/Quad_RecovForest.png", units="in", width=10, height=15, res=300)
plot(p)
dev.off()
null device 
          1 
# ggsave function
ggplot2::ggsave(paste0(saveto,"Quad_RecovForest.png"),
                dpi = 300,
                width = 8, height = 15, units = "in", plot=p)

ggplot2::ggsave(paste0(saveto,"Quad_RecovForest.tiff"),
                dpi = 300,
                width = 8, height = 15, units = "in", plot=p)
dt <- read.csv("~/Documents/GitHub/MPT-Reliability/Recovery/output/combPD_Recovery_Df.csv")[2:7]
dt$id <- unlist(lapply(1:6, function(x) rep(x,times=13)))

dt$Param[dt$Param=="Ab"]<-"Automatic Black"
dt$Param[dt$Param=="Aw"]<-"Automatic White"
dt$Param[dt$Param=="Cb"]<-"Control Black"
dt$Param[dt$Param=="Cw"]<-"Control White"
dt$Param[dt$Param=="Cu"]<-"Control Bad"
dt$Param[dt$Param=="Cp"]<-"Control Good"

dt$Param[dt$Param=="PI"]<-"Project Implicit, 2020"
dt$Param[dt$Param=="Calanchini"]<-"Wilson & Calanchini, 2022"
dt$Param[dt$Param=="Lai1"]<-"Lai et al., 2016 (Study 1)  "
dt$Param[dt$Param=="Lai2"]<-"Lai et al., 2016 (Study 2)  "
dt$Param[dt$Param=="Gawronski"]<-"Gawronski et al., 2017"
dt$Param[dt$Param=="Forscher"]<-"Forscher et al., 2017"

# indent the subgroup if there is a number in the placebo column
dt$Param <- ifelse(dt$type==0, 
                      dt$Param,
                      paste0(" ", dt$Param))

dt$` ` <- paste(rep(" ", 20), collapse = " ")
dt$`Recovery (95% CI)` <- ifelse(is.na(dt$Recov), "",
                             sprintf("%.2f [%.2f, %.2f]",
                                     dt$Recov, dt$CI.LB, dt$CI.UB))

dt2 <- pivot_wider(dt, id_cols = c("Param","id"),  names_from = c(Time), values_from = c(Recov,CI.LB,CI.UB,`Recovery (95% CI)`) )
dt2$`Recovery [95% CI]` <- ifelse(!is.na(dt2$`Recovery (95% CI)_Meta`), paste0("                 ",dt2$`Recovery (95% CI)_Meta`), paste0("T1 :", paste0(dt2$`Recovery (95% CI)_Time1`), " ; ", "T2: ", paste0(dt2$`Recovery (95% CI)_Time2`)))
dt2$` ` <- paste(rep(" ", 20), collapse = " ")


dt3<-dt2 %>% select(Param,Recov_Meta:11,15,16)

colnames(dt3)[colnames(dt3)=="Param"] <- "   "
colnames(dt3)[colnames(dt3)=="Recovery [95% CI]"] <- "    "

dt3$size_Meta <- ifelse(is.na(dt3$Recov_Meta), NA, 1.2)
dt3$size_T1 <- ifelse(is.na(dt3$Recov_Time1), NA, .6)
dt3$size_T2 <- ifelse(is.na(dt3$Recov_Time2), NA, .6)

# Set-up theme
tm <- forest_theme(
                   ci_pch = c(15, 16, 17),
                   ci_col = c("black","red","blue"),
                   ci_lty = c( "solid", "dashed", "dotted"),
                  # footnote_col = "blue",
                   legend_name = " ",
                  legend_position = "bottom",
                   legend_value = c("Meta-Analysis ", "Time 1 ", "Time 2 "))

library(forestploter)
p <- forest(
  dt3[c(1,12,11)],
            est = list(dt3$Recov_Meta, dt3$Recov_Time1, dt3$Recov_Time2),
            lower = list(dt3$CI.LB_Meta, dt3$CI.LB_Time1, dt3$CI.LB_Time2), 
            upper = list(dt3$CI.UB_Meta, dt3$CI.UB_Time1, dt3$CI.UB_Time2),
            ci_column = 2,
            ref_line = .7,
            xlim = c(-.1, 1),
            ticks_at = c(0, .2, .5, .7, 1),
  sizes = list(dt3$size_Meta, dt3$size_T1, dt3$size_T2),
  theme = tm
)
plot(p)


library(grid)
p <- edit_plot(p,
               row = seq(from=1,to=nrow(dt3),by=7),
               gp = gpar(fontface = c("bold","italic")
                         ), col = 1)

studyInds <- setdiff(1:nrow(dt3),seq(from=1,to=nrow(dt3),by=7))
paramInds <- seq(from=1,to=nrow(dt),by=7)

p <- edit_plot(p, row = studyInds, which = "background",
               gp = gpar(fill = "white"))
p <- edit_plot(p, row = paramInds, which = "background",
               gp = gpar(fill = "grey"))
png("~/Desktop/PD_RecovForest.png", units="in", width=10, height=18, res=300)
plot(p)
dev.off()
null device 
          1 
# ggsave function
ggplot2::ggsave(paste0(saveto,"PD_RecovForest.png"),
                dpi = 300,
                width = 8, height = 17, units = "in", plot=p)

ggplot2::ggsave(paste0(saveto,"PD_RecovForest.tiff"),
                dpi = 600,
                width = 8, height = 17, units = "in", plot=p)
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3J9CmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShncmlkKQpsaWJyYXJ5KGZvcmVzdHBsb3RlcikKbGlicmFyeSh0aWR5dmVyc2UpCmBgYAoKYGBge3J9CnNhdmV0byA8LSAiL1ZvbHVtZXMvUmVzZWFyY2ggUHJvamVjdC9JQVRfUmV0ZXN0L1Bsb3R0aW5nL1NhdmVkRmlncy8iCmBgYAoKCgpgYGB7cn0KcGF0aCA8LSAiL1ZvbHVtZXMvIgpzZXR3ZChwYXN0ZTAocGF0aCwiUmVzZWFyY2ggUHJvamVjdC9JQVRfUmV0ZXN0L0VzdGltYXRlcy9VQ1IvIikpCkNhbDEgPC1yZWFkLmNzdigiSW5kaXZpZHVhbFBhcmFtZXRlcnNRdWFkVUNSMS5jc3YiLCBoZWFkZXIgPSBUKQpDYWwyIDwtcmVhZC5jc3YoIkluZGl2aWR1YWxQYXJhbWV0ZXJzUXVhZFVDUjIuY3N2IiwgaGVhZGVyID0gVCkKCmNvbG5hbWVzKENhbDEpWzI6bmNvbChDYWwxKV08LXBhc3RlKGNvbG5hbWVzKENhbDFbMjpuY29sKENhbDEpXSksIlQxIixzZXA9Il8iKQpjb2xuYW1lcyhDYWwyKVsyOm5jb2woQ2FsMildPC1wYXN0ZShjb2xuYW1lcyhDYWwyWzI6bmNvbChDYWwyKV0pLCJUMiIsc2VwPSJfIikKClEuQ2FsIDwtIG1lcmdlKENhbDEsIENhbDIsIGJ5ID0gInN1YmplY3QiLCBhbGwueCA9IFQsIGFsbC55ID0gVCkKCnNldHdkKHBhc3RlMChwYXRoLCJSZXNlYXJjaCBQcm9qZWN0L0lBVF9SZXRlc3QvRXN0aW1hdGVzL1BJLyIpKQpQSTEgPC0gcmVhZC5jc3YoIkluZGl2aWR1YWxQYXJhbWV0ZXJzUXVhZFByb2plY3RJbXBsaWNpdDEuY3N2IikKUEkyIDwtIHJlYWQuY3N2KCJJbmRpdmlkdWFsUGFyYW1ldGVyc1F1YWRQcm9qZWN0SW1wbGljaXQyLmNzdiIpCgpjb2xuYW1lcyhQSTEpWzI6bmNvbChQSTEpXTwtcGFzdGUoY29sbmFtZXMoUEkxWzI6bmNvbChQSTEpXSksIlQxIixzZXA9Il8iKQpjb2xuYW1lcyhQSTIpWzI6bmNvbChQSTIpXTwtcGFzdGUoY29sbmFtZXMoUEkyWzI6bmNvbChQSTIpXSksIlQyIixzZXA9Il8iKQoKUS5QSSA8LSBtZXJnZShQSTEsIFBJMiwgYnkgPSAiSUQiLCBhbGwueCA9IFQsIGFsbC55ID0gVCkKCnNldHdkKHBhc3RlMChwYXRoLCJSZXNlYXJjaCBQcm9qZWN0L0lBVF9SZXRlc3QvRXN0aW1hdGVzL0dhd3JvbnNraS8iKSkKR2F3MSA8LSByZWFkLmNzdigiSW5kaXZpZHVhbFBhcmFtZXRlcnNRdWFkR2F3cm9uc2tpMS5jc3YiKQpHYXcyIDwtIHJlYWQuY3N2KCJJbmRpdmlkdWFsUGFyYW1ldGVyc1F1YWRHYXdyb25za2kyLmNzdiIpCgpjb2xuYW1lcyhHYXcxKVsyOm5jb2woR2F3MSldPC1wYXN0ZShjb2xuYW1lcyhHYXcxWzI6bmNvbChHYXcxKV0pLCJUMSIsc2VwPSJfIikKY29sbmFtZXMoR2F3MilbMjpuY29sKEdhdzIpXTwtcGFzdGUoY29sbmFtZXMoR2F3MlsyOm5jb2woR2F3MildKSwiVDIiLHNlcD0iXyIpCgpRLkdhdyA8LSBtZXJnZShHYXcxLCBHYXcyLCBieSA9ICJjb2RlIiwgYWxsLnggPSBULCBhbGwueSA9IFQpCgpzZXR3ZChwYXN0ZTAocGF0aCwiUmVzZWFyY2ggUHJvamVjdC9JQVRfUmV0ZXN0L0VzdGltYXRlcy9Gb3JzY2hlci8iKSkKRm9yMTwtcmVhZC5jc3YoIkluZGl2aWR1YWxQYXJhbWV0ZXJzUXVhZEZvcnNjaGVyMS5jc3YiLCBoZWFkZXIgPSBUKQpGb3IyPC1yZWFkLmNzdigiSW5kaXZpZHVhbFBhcmFtZXRlcnNRdWFkRm9yc2NoZXIyLmNzdiIsIGhlYWRlciA9IFQpCgpjb2xuYW1lcyhGb3IxKVsyOm5jb2woRm9yMSldPC1wYXN0ZShjb2xuYW1lcyhGb3IxWzI6bmNvbChGb3IxKV0pLCJUMSIsc2VwPSJfIikKY29sbmFtZXMoRm9yMilbMjpuY29sKEZvcjIpXTwtcGFzdGUoY29sbmFtZXMoRm9yMlsyOm5jb2woRm9yMildKSwiVDIiLHNlcD0iXyIpCgpRLkZvciA8LSBtZXJnZShGb3IxLCBGb3IyLCBieSA9ICJzdWJqZWN0IiwgYWxsLnggPSBULCBhbGwueSA9IFQpCgpzZXR3ZChwYXN0ZTAocGF0aCwiUmVzZWFyY2ggUHJvamVjdC9JQVRfUmV0ZXN0L0VzdGltYXRlcy9MYWkxLyIpKQpMYWkxMTwtcmVhZC5jc3YoIkluZGl2aWR1YWxQYXJhbWV0ZXJzTGFpU3R1ZHkxUXVhZDEuY3N2IiwgaGVhZGVyID0gVCkKTGFpMTI8LXJlYWQuY3N2KCJJbmRpdmlkdWFsUGFyYW1ldGVyc0xhaVN0dWR5MVF1YWQyLmNzdiIsIGhlYWRlciA9IFQpCgpjb2xuYW1lcyhMYWkxMSlbMjpuY29sKExhaTExKV08LXBhc3RlKGNvbG5hbWVzKExhaTExWzI6bmNvbChMYWkxMSldKSwiVDEiLHNlcD0iXyIpCmNvbG5hbWVzKExhaTEyKVsyOm5jb2woTGFpMTIpXTwtcGFzdGUoY29sbmFtZXMoTGFpMTJbMjpuY29sKExhaTEyKV0pLCJUMiIsc2VwPSJfIikKClEuTGFpMSA8LSBtZXJnZShMYWkxMSwgTGFpMTIsIGJ5ID0gInNlc3Npb25faWQiLCBhbGwueCA9IFQsIGFsbC55ID0gVCkKCnNldHdkKHBhc3RlMChwYXRoLCJSZXNlYXJjaCBQcm9qZWN0L0lBVF9SZXRlc3QvRXN0aW1hdGVzL0xhaTIvIikpCkxhaTIxPC1yZWFkLmNzdigiSW5kaXZpZHVhbFBhcmFtZXRlcnNMYWlTdHVkeTJRdWFkMS5jc3YiLCBoZWFkZXIgPSBUKQpMYWkyMjwtcmVhZC5jc3YoIkluZGl2aWR1YWxQYXJhbWV0ZXJzTGFpU3R1ZHkyUXVhZDIuY3N2IiwgaGVhZGVyID0gVCkKCmNvbG5hbWVzKExhaTIxKVsyOm5jb2woTGFpMjEpXTwtcGFzdGUoY29sbmFtZXMoTGFpMjFbMjpuY29sKExhaTIxKV0pLCJUMSIsc2VwPSJfIikKY29sbmFtZXMoTGFpMjIpWzI6bmNvbChMYWkyMildPC1wYXN0ZShjb2xuYW1lcyhMYWkyMlsyOm5jb2woTGFpMjIpXSksIlQyIixzZXA9Il8iKQoKUS5MYWkyIDwtIG1lcmdlKExhaTIxLCBMYWkyMiwgYnkgPSAic2Vzc2lvbl9pZCIsIGFsbC54ID0gVCwgYWxsLnkgPSBUKQoKY29sbmFtZXMoUS5DYWwpWzFdIDwtICJzdWJJRCIKUS5DYWwgPC0gY2JpbmQoUS5DYWwsIFN0dWR5ID0gIkNhbGFuY2hpbmkiKQpjb2xuYW1lcyhRLlBJKVsxXSA8LSAic3ViSUQiClEuUEkgPC0gY2JpbmQoUS5QSSwgU3R1ZHkgPSAiUEkiKQpjb2xuYW1lcyhRLkdhdylbMV0gPC0gInN1YklEIgpRLkdhdyA8LSBjYmluZChRLkdhdywgU3R1ZHkgPSAiR2F3cm9uc2tpIikKY29sbmFtZXMoUS5Gb3IpWzFdIDwtICJzdWJJRCIKUS5Gb3IgPC0gY2JpbmQoUS5Gb3IsIFN0dWR5ID0gIkZvcnNjaGVyIikKY29sbmFtZXMoUS5MYWkxKVsxXSA8LSAic3ViSUQiClEuTGFpMSA8LSBjYmluZChRLkxhaTEsIFN0dWR5ID0gIkxhaSAxIikKY29sbmFtZXMoUS5MYWkyKVsxXSA8LSAic3ViSUQiClEuTGFpMiA8LSBjYmluZChRLkxhaTIsIFN0dWR5ID0gIkxhaSAyIikKClF1YWQgPC0gcmJpbmQoUS5DYWwsUS5QSSxRLkdhdyxRLkZvcixRLkxhaTEsUS5MYWkyKQoKClF1YWQkU3R1ZHlbUXVhZCRTdHVkeT09IlBJIl08LSJQcm9qZWN0IEltcGxpY2l0LCAyMDIwIgpRdWFkJFN0dWR5W1F1YWQkU3R1ZHk9PSJDYWxhbmNoaW5pIl08LSJXaWxzb24gJiBDYWxhbmNoaW5pLCAyMDIyIgpRdWFkJFN0dWR5W1F1YWQkU3R1ZHk9PSJMYWkgMSJdPC0iTGFpIGV0IGFsLiwgMjAxNiAoU3R1ZHkgMSkgICIKUXVhZCRTdHVkeVtRdWFkJFN0dWR5PT0iTGFpIDIiXTwtIkxhaSBldCBhbC4sIDIwMTYgKFN0dWR5IDIpICAiClF1YWQkU3R1ZHlbUXVhZCRTdHVkeT09Ikdhd3JvbnNraSJdPC0iR2F3cm9uc2tpIGV0IGFsLiwgMjAxNyIKUXVhZCRTdHVkeVtRdWFkJFN0dWR5PT0iRm9yc2NoZXIiXTwtIkZvcnNjaGVyIGV0IGFsLiwgMjAxNyIKYGBgCgpgYGB7cn0KcGF0aCA8LSAiL1ZvbHVtZXMvIgpzZXR3ZChwYXN0ZTAocGF0aCwiUmVzZWFyY2ggUHJvamVjdC9JQVRfUmV0ZXN0L0VzdGltYXRlcy9VQ1IvIikpCkNhbDEgPC1yZWFkLmNzdigiSW5kaXZpZHVhbFBhcmFtZXRlcnNQRFVDUjEuY3N2IiwgaGVhZGVyID0gVCkKQ2FsMiA8LXJlYWQuY3N2KCJJbmRpdmlkdWFsUGFyYW1ldGVyc1BEVUNSMi5jc3YiLCBoZWFkZXIgPSBUKQoKY29sbmFtZXMoQ2FsMSlbMjpuY29sKENhbDEpXTwtcGFzdGUoY29sbmFtZXMoQ2FsMVsyOm5jb2woQ2FsMSldKSwiVDEiLHNlcD0iXyIpCmNvbG5hbWVzKENhbDIpWzI6bmNvbChDYWwyKV08LXBhc3RlKGNvbG5hbWVzKENhbDJbMjpuY29sKENhbDIpXSksIlQyIixzZXA9Il8iKQoKUC5DYWwgPC0gbWVyZ2UoQ2FsMSwgQ2FsMiwgYnkgPSAic3ViamVjdCIsIGFsbC54ID0gVCwgYWxsLnkgPSBUKQoKc2V0d2QocGFzdGUwKHBhdGgsIlJlc2VhcmNoIFByb2plY3QvSUFUX1JldGVzdC9Fc3RpbWF0ZXMvUEkvIikpClBJMSA8LSByZWFkLmNzdigiSW5kaXZpZHVhbFBhcmFtZXRlcnNQcm9qZWN0SW1wbGljaXRQRDEuY3N2IikKUEkyIDwtIHJlYWQuY3N2KCJJbmRpdmlkdWFsUGFyYW1ldGVyc1Byb2plY3RJbXBsaWNpdFBEMi5jc3YiKQoKY29sbmFtZXMoUEkxKVsyOm5jb2woUEkxKV08LXBhc3RlKGNvbG5hbWVzKFBJMVsyOm5jb2woUEkxKV0pLCJUMSIsc2VwPSJfIikKY29sbmFtZXMoUEkyKVsyOm5jb2woUEkyKV08LXBhc3RlKGNvbG5hbWVzKFBJMlsyOm5jb2woUEkyKV0pLCJUMiIsc2VwPSJfIikKClAuUEkgPC0gbWVyZ2UoUEkxLCBQSTIsIGJ5ID0gIklEIiwgYWxsLnggPSBULCBhbGwueSA9IFQpCgpzZXR3ZChwYXN0ZTAocGF0aCwiUmVzZWFyY2ggUHJvamVjdC9JQVRfUmV0ZXN0L0VzdGltYXRlcy9HYXdyb25za2kvIikpCkdhdzEgPC0gcmVhZC5jc3YoIkluZGl2aWR1YWxQYXJhbWV0ZXJzUERHYXdyb25za2kxLmNzdiIpCkdhdzIgPC0gcmVhZC5jc3YoIkluZGl2aWR1YWxQYXJhbWV0ZXJzUERHYXdyb25za2kyLmNzdiIpCgpjb2xuYW1lcyhHYXcxKVsyOm5jb2woR2F3MSldPC1wYXN0ZShjb2xuYW1lcyhHYXcxWzI6bmNvbChHYXcxKV0pLCJUMSIsc2VwPSJfIikKY29sbmFtZXMoR2F3MilbMjpuY29sKEdhdzIpXTwtcGFzdGUoY29sbmFtZXMoR2F3MlsyOm5jb2woR2F3MildKSwiVDIiLHNlcD0iXyIpCgpQLkdhdyA8LSBtZXJnZShHYXcxLCBHYXcyLCBieSA9ICJjb2RlIiwgYWxsLnggPSBULCBhbGwueSA9IFQpCgpzZXR3ZChwYXN0ZTAocGF0aCwiUmVzZWFyY2ggUHJvamVjdC9JQVRfUmV0ZXN0L0VzdGltYXRlcy9Gb3JzY2hlci8iKSkKRm9yMTwtcmVhZC5jc3YoIkluZGl2aWR1YWxQYXJhbWV0ZXJzRm9yc2NoZXJQRDEuY3N2IiwgaGVhZGVyID0gVCkKRm9yMjwtcmVhZC5jc3YoIkluZGl2aWR1YWxQYXJhbWV0ZXJzRm9yc2NoZXJQRDIuY3N2IiwgaGVhZGVyID0gVCkKCmNvbG5hbWVzKEZvcjEpWzI6bmNvbChGb3IxKV08LXBhc3RlKGNvbG5hbWVzKEZvcjFbMjpuY29sKEZvcjEpXSksIlQxIixzZXA9Il8iKQpjb2xuYW1lcyhGb3IyKVsyOm5jb2woRm9yMildPC1wYXN0ZShjb2xuYW1lcyhGb3IyWzI6bmNvbChGb3IyKV0pLCJUMiIsc2VwPSJfIikKClAuRm9yIDwtIG1lcmdlKEZvcjEsIEZvcjIsIGJ5ID0gInN1YmplY3QiLCBhbGwueCA9IFQsIGFsbC55ID0gVCkKCnNldHdkKHBhc3RlMChwYXRoLCJSZXNlYXJjaCBQcm9qZWN0L0lBVF9SZXRlc3QvRXN0aW1hdGVzL0xhaTEvIikpCkxhaTExPC1yZWFkLmNzdigiSW5kaXZpZHVhbFBhcmFtZXRlcnNMYWlTdHVkeTFQRDEuY3N2IiwgaGVhZGVyID0gVCkKTGFpMTI8LXJlYWQuY3N2KCJJbmRpdmlkdWFsUGFyYW1ldGVyc0xhaVN0dWR5MVBEMi5jc3YiLCBoZWFkZXIgPSBUKQoKY29sbmFtZXMoTGFpMTEpWzI6bmNvbChMYWkxMSldPC1wYXN0ZShjb2xuYW1lcyhMYWkxMVsyOm5jb2woTGFpMTEpXSksIlQxIixzZXA9Il8iKQpjb2xuYW1lcyhMYWkxMilbMjpuY29sKExhaTEyKV08LXBhc3RlKGNvbG5hbWVzKExhaTEyWzI6bmNvbChMYWkxMildKSwiVDIiLHNlcD0iXyIpCgpQLkxhaTEgPC0gbWVyZ2UoTGFpMTEsIExhaTEyLCBieSA9ICJzZXNzaW9uX2lkIiwgYWxsLnggPSBULCBhbGwueSA9IFQpCgpzZXR3ZChwYXN0ZTAocGF0aCwiUmVzZWFyY2ggUHJvamVjdC9JQVRfUmV0ZXN0L0VzdGltYXRlcy9MYWkyLyIpKQpMYWkyMTwtcmVhZC5jc3YoIkluZGl2aWR1YWxQYXJhbWV0ZXJzTGFpU3R1ZHkyUEQxLmNzdiIsIGhlYWRlciA9IFQpCkxhaTIyPC1yZWFkLmNzdigiSW5kaXZpZHVhbFBhcmFtZXRlcnNMYWlTdHVkeTJQRDIuY3N2IiwgaGVhZGVyID0gVCkKCmNvbG5hbWVzKExhaTIxKVsyOm5jb2woTGFpMjEpXTwtcGFzdGUoY29sbmFtZXMoTGFpMjFbMjpuY29sKExhaTIxKV0pLCJUMSIsc2VwPSJfIikKY29sbmFtZXMoTGFpMjIpWzI6bmNvbChMYWkyMildPC1wYXN0ZShjb2xuYW1lcyhMYWkyMlsyOm5jb2woTGFpMjIpXSksIlQyIixzZXA9Il8iKQoKUC5MYWkyIDwtIG1lcmdlKExhaTIxLCBMYWkyMiwgYnkgPSAic2Vzc2lvbl9pZCIsIGFsbC54ID0gVCwgYWxsLnkgPSBUKQoKY29sbmFtZXMoUC5DYWwpWzFdIDwtICJzdWJJRCIKUC5DYWwgPC0gY2JpbmQoUC5DYWwsIFN0dWR5ID0gIkNhbGFuY2hpbmkiKQpjb2xuYW1lcyhQLlBJKVsxXSA8LSAic3ViSUQiClAuUEkgPC0gY2JpbmQoUC5QSSwgU3R1ZHkgPSAiUEkiKQpjb2xuYW1lcyhQLkdhdylbMV0gPC0gInN1YklEIgpQLkdhdyA8LSBjYmluZChQLkdhdywgU3R1ZHkgPSAiR2F3cm9uc2tpIikKY29sbmFtZXMoUC5Gb3IpWzFdIDwtICJzdWJJRCIKUC5Gb3IgPC0gY2JpbmQoUC5Gb3IsIFN0dWR5ID0gIkZvcnNjaGVyIikKY29sbmFtZXMoUC5MYWkxKVsxXSA8LSAic3ViSUQiClAuTGFpMSA8LSBjYmluZChQLkxhaTEsIFN0dWR5ID0gIkxhaSAxIikKY29sbmFtZXMoUC5MYWkyKVsxXSA8LSAic3ViSUQiClAuTGFpMiA8LSBjYmluZChQLkxhaTIsIFN0dWR5ID0gIkxhaSAyIikKClBEIDwtIHJiaW5kKFAuQ2FsLFAuUEksUC5HYXcsUC5Gb3IsUC5MYWkxLFAuTGFpMikKClBEJFN0dWR5W1BEJFN0dWR5PT0iUEkiXTwtIlByb2plY3QgSW1wbGljaXQsIDIwMjAiClBEJFN0dWR5W1BEJFN0dWR5PT0iQ2FsYW5jaGluaSJdPC0iV2lsc29uICYgQ2FsYW5jaGluaSwgMjAyMiIKUEQkU3R1ZHlbUEQkU3R1ZHk9PSJMYWkgMSJdPC0iTGFpIGV0IGFsLiwgMjAxNiAoU3R1ZHkgMSkgICIKUEQkU3R1ZHlbUEQkU3R1ZHk9PSJMYWkgMiJdPC0iTGFpIGV0IGFsLiwgMjAxNiAoU3R1ZHkgMikgICIKUEQkU3R1ZHlbUEQkU3R1ZHk9PSJHYXdyb25za2kiXTwtIkdhd3JvbnNraSBldCBhbC4sIDIwMTciClBEJFN0dWR5W1BEJFN0dWR5PT0iRm9yc2NoZXIiXTwtIkZvcnNjaGVyIGV0IGFsLiwgMjAxNyIKYGBgCgojIFF1YWQgTW9kZWwKCiMjIEFzc29jaWF0ZSBCbGFjay1CYWQKCmBgYHtyfQpBQ2JiU2NhdHRlciA8LSBnZ3Bsb3QoUXVhZCwgYWVzKHg9QUNiYjFfVDEsIHk9QUNiYjFfVDIsIGNvbG9yPVN0dWR5KSkgKyAKICBnZW9tX3BvaW50KGFscGhhID0gLjIpKwogIGdlb21fc21vb3RoKG1ldGhvZD1sbSwgc2U9VFJVRSwgbGluZXR5cGU9ImRhc2hlZCIsCiAgICAgICAgICAgICBjb2xvcj0iZ3JleSIpICArIGdlb21fYWJsaW5lKGludGVyY2VwdCA9IDAsIHNsb3BlID0gMSkgKyB5bGltKDAsMSkgKyB4bGltKDAsMSkgKyBsYWJzKHRpdGxlPSJBc3NvY2lhdGlvbiBCbGFjay1CYWQiLAogICAgICAgeD0iVGltZSAxIiwgeSA9ICJUaW1lIDIiKSArIGd1aWRlcyhjb2xvdXIgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChhbHBoYSA9IDEpKSkgKwogIGp0b29sczo6dGhlbWVfYXBhKCkgCkFDYmJTY2F0dGVyCmdnc2F2ZShwYXN0ZTAoc2F2ZXRvLCJBQ2JiU2NhdHRlci5qcGciKSxkcGk9NjAwKQpnZ3NhdmUocGFzdGUwKHNhdmV0bywiQUNiYlNjYXR0ZXIudGlmZiIpLGRwaT02MDApCmBgYAoKIyMgQXNzb2NpYXRlIFdoaXRlLUdvb2QKCmBgYHtyfQpBQ3dnU2NhdHRlciA8LSBnZ3Bsb3QoUXVhZCwgYWVzKHg9QUN3ZzFfVDEsIHk9QUN3ZzFfVDIsIGNvbG9yPVN0dWR5KSkgKyAKICBnZW9tX3BvaW50KGFscGhhID0gLjIpKwogIGdlb21fc21vb3RoKG1ldGhvZD1sbSwgc2U9VFJVRSwgbGluZXR5cGU9ImRhc2hlZCIsCiAgICAgICAgICAgICBjb2xvcj0iZ3JleSIpICArIGdlb21fYWJsaW5lKGludGVyY2VwdCA9IDAsIHNsb3BlID0gMSkgKyB5bGltKDAsMSkgKyB4bGltKDAsMSkgKyBsYWJzKHRpdGxlPSJBc3NvY2lhdGlvbiBXaGl0ZS1Hb29kIiwKICAgICAgIHg9IlRpbWUgMSIsIHkgPSAiVGltZSAyIikgKyBndWlkZXMoY29sb3VyID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3QoYWxwaGEgPSAxKSkpICsgdGhlbWUobGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSA5KSkgKwogIGp0b29sczo6dGhlbWVfYXBhKCkKQUN3Z1NjYXR0ZXIKZ2dzYXZlKHBhc3RlMChzYXZldG8sIkFDd2dTY2F0dGVyLmpwZyIpLGRwaT02MDApCmdnc2F2ZShwYXN0ZTAoc2F2ZXRvLCJBQ3dnU2NhdHRlci50aWZmIiksZHBpPTYwMCkKYGBgCgojIyBEZXRlY3Rpb24KCmBgYHtyfQpEU2NhdHRlciA8LSBnZ3Bsb3QoUXVhZCwgYWVzKHg9RDFfVDEsIHk9RDFfVDIsIGNvbG9yPVN0dWR5KSkgKyAKICBnZW9tX3BvaW50KGFscGhhID0gLjIpKwogIGdlb21fc21vb3RoKG1ldGhvZD1sbSwgc2U9VFJVRSwgbGluZXR5cGU9ImRhc2hlZCIsCiAgICAgICAgICAgICBjb2xvcj0iZ3JleSIpICArIGdlb21fYWJsaW5lKGludGVyY2VwdCA9IDAsIHNsb3BlID0gMSkgKyB5bGltKDAsMSkgKyB4bGltKDAsMSkgKyBsYWJzKHRpdGxlPSJEZXRlY3Rpb24iLAogICAgICAgeD0iVGltZSAxIiwgeSA9ICJUaW1lIDIiKSArIGd1aWRlcyhjb2xvdXIgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChhbHBoYSA9IDEpKSkgKyB0aGVtZShsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDkpKSArCiAganRvb2xzOjp0aGVtZV9hcGEoKQpEU2NhdHRlcgpnZ3NhdmUocGFzdGUwKHNhdmV0bywiRFNjYXR0ZXIuanBnIiksZHBpPTYwMCkKZ2dzYXZlKHBhc3RlMChzYXZldG8sIkRTY2F0dGVyLnRpZmYiKSxkcGk9NjAwKQpgYGAKCiMjIE92ZXJjb21pbmcgQmlhcwoKYGBge3J9Ck9CU2NhdHRlciA8LSBnZ3Bsb3QoUXVhZCwgYWVzKHg9T0IxX1QxLCB5PU9CMV9UMiwgY29sb3I9U3R1ZHkpKSArIAogIGdlb21fcG9pbnQoYWxwaGEgPSAuMikrCiAgZ2VvbV9zbW9vdGgobWV0aG9kPWxtLCBzZT1UUlVFLCBsaW5ldHlwZT0iZGFzaGVkIiwKICAgICAgICAgICAgIGNvbG9yPSJncmV5IikgICsgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0ID0gMCwgc2xvcGUgPSAxKSArIHlsaW0oMCwxKSArIHhsaW0oMCwxKSArIGxhYnModGl0bGU9Ik92ZXJjb21pbmcgQmlhcyIsCiAgICAgICB4PSJUaW1lIDEiLCB5ID0gIlRpbWUgMiIpICsgZ3VpZGVzKGNvbG91ciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KGFscGhhID0gMSkpKSArIHRoZW1lKGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gOSkpICArCiAganRvb2xzOjp0aGVtZV9hcGEoKQpPQlNjYXR0ZXIKZ2dzYXZlKHBhc3RlMChzYXZldG8sIk9CU2NhdHRlci5qcGciKSxkcGk9NjAwKQpnZ3NhdmUocGFzdGUwKHNhdmV0bywiT0JTY2F0dGVyLnRpZmYiKSxkcGk9NjAwKQpgYGAKCiMjIEd1ZXNzaW5nCgpgYGB7cn0KR1NjYXR0ZXIgPC0gZ2dwbG90KFF1YWQsIGFlcyh4PUcxX1QxLCB5PUcxX1QyLCBjb2xvcj1TdHVkeSkpICsgCiAgZ2VvbV9wb2ludChhbHBoYSA9IC4yKSsKICBnZW9tX3Ntb290aChtZXRob2Q9bG0sIHNlPVRSVUUsIGxpbmV0eXBlPSJkYXNoZWQiLAogICAgICAgICAgICAgY29sb3I9ImdyZXkiKSAgKyBnZW9tX2FibGluZShpbnRlcmNlcHQgPSAwLCBzbG9wZSA9IDEpICsgeWxpbSgwLDEpICsgeGxpbSgwLDEpICsgbGFicyh0aXRsZT0iR3Vlc3NpbmciLAogICAgICAgeD0iVGltZSAxIiwgeSA9ICJUaW1lIDIiKSArIGd1aWRlcyhjb2xvdXIgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChhbHBoYSA9IDEpKSkgKwogIGp0b29sczo6dGhlbWVfYXBhKCkKZ2dzYXZlKHBhc3RlMChzYXZldG8sIkdTY2F0dGVyLmpwZyIpLGRwaT02MDApCmdnc2F2ZShwYXN0ZTAoc2F2ZXRvLCJHU2NhdHRlci50aWZmIiksZHBpPTYwMCkKYGBgCgojIyBQYW5lbAoKYGBge3J9CmxpYnJhcnkoZ2dwdWJyKQpRdWFkUGFuZWwxIDwtIGdnYXJyYW5nZShBQ3dnU2NhdHRlciwgQUNiYlNjYXR0ZXIsIERTY2F0dGVyLCBPQlNjYXR0ZXIsIEdTY2F0dGVyLAogICAgICAgICAgbmNvbCA9IDMsIG5yb3cgPSAyLCBjb21tb24ubGVnZW5kID0gVCkKUXVhZFBhbmVsMQoKcmVxdWlyZShncmlkKSAgICMgZm9yIHRoZSB0ZXh0R3JvYigpIGZ1bmN0aW9uCgpRdWFkUGFuZWwyIDwtIGdnYXJyYW5nZShBQ3dnU2NhdHRlciAgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTIpKSArIHRoZW1lKGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4KSkgKyBycmVtb3ZlKCJ5bGFiIikgKyBycmVtb3ZlKCJ4bGFiIiksIAogICAgICAgICAgICAgICAgICAgICAgICBBQ2JiU2NhdHRlciAgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTIpKSArIHJyZW1vdmUoInlsYWIiKSArIHJyZW1vdmUoInhsYWIiKSwKICAgICAgICAgICAgICAgICAgICAgICAgRFNjYXR0ZXIgICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSkgKyBycmVtb3ZlKCJ5bGFiIikgKyBycmVtb3ZlKCJ4bGFiIiksCiAgICAgICAgICAgICAgICAgICAgICAgIE9CU2NhdHRlciAgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTIpKSArIHJyZW1vdmUoInlsYWIiKSArIHJyZW1vdmUoInhsYWIiKSwKICAgICAgICAgICAgICAgICAgICAgICAgR1NjYXR0ZXIgICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSkgKyBycmVtb3ZlKCJ5bGFiIikgKyBycmVtb3ZlKCJ4bGFiIiksCiAgICAgICAgICBuY29sID0gMywgbnJvdyA9IDIsIGNvbW1vbi5sZWdlbmQgPSBULCBsYWJlbHMgPSBOVUxMLCBsZWdlbmQgPSAiYm90dG9tIiwKICAgICAgICAgIGFsaWduID0gImh2IiwgCiAgICAgICAgICAgICAgICAgICAgZm9udC5sYWJlbCA9IGxpc3Qoc2l6ZSA9IDEwLCBjb2xvciA9ICJibGFjayIsIGZhY2UgPSAiYm9sZCIsIGZhbWlseSA9IE5VTEwsIHBvc2l0aW9uID0gInRvcCIpKQpRdWFkUGFuZWwyCgphbm5vdGF0ZV9maWd1cmUoUXVhZFBhbmVsMiwgbGVmdCA9IHRleHRHcm9iKCJUaW1lIDIiLCByb3QgPSA5MCwgdmp1c3QgPSAxLCBoanVzdCA9IDAsIGdwID0gZ3BhcihjZXggPSAxKSksCiAgICAgICAgICAgICAgICAgICAgYm90dG9tID0gdGV4dEdyb2IoIlRpbWUgMSIsIHZqdXN0ID0gLTYuNSwgZ3AgPSBncGFyKGNleCA9IDEpKSkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSBjKDAsLTEpKQpnZ3NhdmUocGFzdGUwKHNhdmV0bywiUXVhZFBhbmVsLmpwZyIpLGRwaT02MDApCmdnc2F2ZShwYXN0ZTAoc2F2ZXRvLCJRdWFkUGFuZWwudGlmZiIpLGRwaT02MDApCmBgYAoKCiMgUEQgTW9kZWwKCiMjIEF1dG9tYXRpYyBCbGFjawoKYGBge3J9CkFiU2NhdHRlciA8LSBnZ3Bsb3QoUEQsIGFlcyh4PUFiMV9UMSwgeT1BYjFfVDIsIGNvbG9yPVN0dWR5KSkgKyAKICBnZW9tX3BvaW50KGFscGhhID0gLjIpKwogIGdlb21fc21vb3RoKG1ldGhvZD1sbSwgc2U9VFJVRSwgbGluZXR5cGU9ImRhc2hlZCIsCiAgICAgICAgICAgICBjb2xvcj0iZ3JleSIpICArIGdlb21fYWJsaW5lKGludGVyY2VwdCA9IDAsIHNsb3BlID0gMSkgKyB5bGltKDAsMSkgKyB4bGltKDAsMSkgKyBsYWJzKHRpdGxlPSJBdXRvbWF0aWMgQmxhY2siLAogICAgICAgeD0iVGltZSAxIiwgeSA9ICJUaW1lIDIiKSArIGd1aWRlcyhjb2xvdXIgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChhbHBoYSA9IDEpKSkgKwogIGp0b29sczo6dGhlbWVfYXBhKCkKQWJTY2F0dGVyCmdnc2F2ZShwYXN0ZTAoc2F2ZXRvLCJBYlNjYXR0ZXIuanBnIiksZHBpPTYwMCkKZ2dzYXZlKHBhc3RlMChzYXZldG8sIkFiU2NhdHRlci50aWZmIiksZHBpPTYwMCkKYGBgCgojIyBBc3NvY2lhdGUgV2hpdGUKCmBgYHtyfQpBd1NjYXR0ZXIgPC0gZ2dwbG90KFBELCBhZXMoeD1BdzFfVDEsIHk9QXcxX1QyLCBjb2xvcj1TdHVkeSkpICsgCiAgZ2VvbV9wb2ludChhbHBoYSA9IC4yKSsKICBnZW9tX3Ntb290aChtZXRob2Q9bG0sIHNlPVRSVUUsIGxpbmV0eXBlPSJkYXNoZWQiLAogICAgICAgICAgICAgY29sb3I9ImdyZXkiKSAgKyBnZW9tX2FibGluZShpbnRlcmNlcHQgPSAwLCBzbG9wZSA9IDEpICsgeWxpbSgwLDEpICsgeGxpbSgwLDEpICsgbGFicyh0aXRsZT0iQXV0b21hdGljIFdoaXRlIiwKICAgICAgIHg9IlRpbWUgMSIsIHkgPSAiVGltZSAyIikgKyBndWlkZXMoY29sb3VyID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3QoYWxwaGEgPSAxKSkpICsKICBqdG9vbHM6OnRoZW1lX2FwYSgpCkF3U2NhdHRlcgpnZ3NhdmUocGFzdGUwKHNhdmV0bywiQXdTY2F0dGVyLmpwZyIpLGRwaT02MDApCmdnc2F2ZShwYXN0ZTAoc2F2ZXRvLCJBd1NjYXR0ZXIudGlmZiIpLGRwaT02MDApCmBgYAoKIyMgQ29udHJvbCBHb29kCgpgYGB7cn0KQ3BTY2F0dGVyIDwtIGdncGxvdChQRCwgYWVzKHg9Q3AxX1QxLCB5PUNwMV9UMiwgY29sb3I9U3R1ZHkpKSArIAogIGdlb21fcG9pbnQoYWxwaGEgPSAuMikrCiAgZ2VvbV9zbW9vdGgobWV0aG9kPWxtLCBzZT1UUlVFLCBsaW5ldHlwZT0iZGFzaGVkIiwKICAgICAgICAgICAgIGNvbG9yPSJncmV5IikgICsgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0ID0gMCwgc2xvcGUgPSAxKSArIHlsaW0oMCwxKSArIHhsaW0oMCwxKSArIGxhYnModGl0bGU9IkNvbnRyb2wgR29vZCIsCiAgICAgICB4PSJUaW1lIDEiLCB5ID0gIlRpbWUgMiIpICsgZ3VpZGVzKGNvbG91ciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KGFscGhhID0gMSkpKSArCiAganRvb2xzOjp0aGVtZV9hcGEoKQpDcFNjYXR0ZXIKZ2dzYXZlKHBhc3RlMChzYXZldG8sIkNwU2NhdHRlci5qcGciKSxkcGk9NjAwKQpnZ3NhdmUocGFzdGUwKHNhdmV0bywiQ3BTY2F0dGVyLnRpZmYiKSxkcGk9NjAwKQpgYGAKCiMjIENvbnRyb2wgQmFkCgpgYGB7cn0KQ3VTY2F0dGVyIDwtIGdncGxvdChQRCwgYWVzKHg9Q3UxX1QxLCB5PUN1MV9UMiwgY29sb3I9U3R1ZHkpKSArIAogIGdlb21fcG9pbnQoYWxwaGEgPSAuMikrCiAgZ2VvbV9zbW9vdGgobWV0aG9kPWxtLCBzZT1UUlVFLCBsaW5ldHlwZT0iZGFzaGVkIiwKICAgICAgICAgICAgIGNvbG9yPSJncmV5IikgICsgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0ID0gMCwgc2xvcGUgPSAxKSArIHlsaW0oMCwxKSArIHhsaW0oMCwxKSArIGxhYnModGl0bGU9IkNvbnRyb2wgQmFkIiwKICAgICAgIHg9IlRpbWUgMSIsIHkgPSAiVGltZSAyIikgKyBndWlkZXMoY29sb3VyID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3QoYWxwaGEgPSAxKSkpICsKICBqdG9vbHM6OnRoZW1lX2FwYSgpCkN1U2NhdHRlcgpnZ3NhdmUocGFzdGUwKHNhdmV0bywiQ3VTY2F0dGVyLmpwZyIpLGRwaT02MDApCmdnc2F2ZShwYXN0ZTAoc2F2ZXRvLCJDdVNjYXR0ZXIudGlmZiIpLGRwaT02MDApCmBgYAoKIyMgQ29udHJvbCBXaGl0ZQoKYGBge3J9CkN3U2NhdHRlciA8LSBnZ3Bsb3QoUEQsIGFlcyh4PUN3MV9UMSwgeT1DdzFfVDIsIGNvbG9yPVN0dWR5KSkgKyAKICBnZW9tX3BvaW50KGFscGhhID0gLjIpKwogIGdlb21fc21vb3RoKG1ldGhvZD1sbSwgc2U9VFJVRSwgbGluZXR5cGU9ImRhc2hlZCIsCiAgICAgICAgICAgICBjb2xvcj0iZ3JleSIpICArIGdlb21fYWJsaW5lKGludGVyY2VwdCA9IDAsIHNsb3BlID0gMSkgKyB5bGltKDAsMSkgKyB4bGltKDAsMSkgKyBsYWJzKHRpdGxlPSJDb250cm9sIFdoaXRlIiwKICAgICAgIHg9IlRpbWUgMSIsIHkgPSAiVGltZSAyIikgKyBndWlkZXMoY29sb3VyID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3QoYWxwaGEgPSAxKSkpICsKICBqdG9vbHM6OnRoZW1lX2FwYSgpCkN3U2NhdHRlcgpnZ3NhdmUocGFzdGUwKHNhdmV0bywiQ3dTY2F0dGVyLmpwZyIpLGRwaT02MDApCmdnc2F2ZShwYXN0ZTAoc2F2ZXRvLCJDd1NjYXR0ZXIudGlmZiIpLGRwaT02MDApCmBgYAoKIyMgQ29udHJvbCBCbGFjawoKYGBge3J9CkNiU2NhdHRlciA8LSBnZ3Bsb3QoUEQsIGFlcyh4PUNiMV9UMSwgeT1DYjFfVDIsIGNvbG9yPVN0dWR5KSkgKyAKICBnZW9tX3BvaW50KGFscGhhID0gLjIpKwogIGdlb21fc21vb3RoKG1ldGhvZD1sbSwgc2U9VFJVRSwgbGluZXR5cGU9ImRhc2hlZCIsCiAgICAgICAgICAgICBjb2xvcj0iZ3JleSIpICArIGdlb21fYWJsaW5lKGludGVyY2VwdCA9IDAsIHNsb3BlID0gMSkgKyB5bGltKDAsMSkgKyB4bGltKDAsMSkgKyBsYWJzKHRpdGxlPSJDb250cm9sIEJsYWNrIiwKICAgICAgIHg9IlRpbWUgMSIsIHkgPSAiVGltZSAyIikgKyBndWlkZXMoY29sb3VyID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3QoYWxwaGEgPSAxKSkpICsKICBqdG9vbHM6OnRoZW1lX2FwYSgpCkNiU2NhdHRlcgpnZ3NhdmUocGFzdGUwKHNhdmV0bywiQ2JTY2F0dGVyLmpwZyIpLGRwaT02MDApCmdnc2F2ZShwYXN0ZTAoc2F2ZXRvLCJDYlNjYXR0ZXIudGlmZiIpLGRwaT02MDApCmBgYAoKIyMgUGFuZWwKCmBgYHtyfQpsaWJyYXJ5KGdncHVicikKUERQYW5lbDEgPC0gZ2dhcnJhbmdlKEF3U2NhdHRlciwgQWJTY2F0dGVyLCBDdVNjYXR0ZXIsIENwU2NhdHRlciwgQ2JTY2F0dGVyLCBDd1NjYXR0ZXIsCiAgICAgICAgICBuY29sID0gMywgbnJvdyA9IDIsIGNvbW1vbi5sZWdlbmQgPSBUKQpQRFBhbmVsMQoKcmVxdWlyZShncmlkKSAgICMgZm9yIHRoZSB0ZXh0R3JvYigpIGZ1bmN0aW9uCgpQRFBhbmVsMiA8LSBnZ2FycmFuZ2UoQXdTY2F0dGVyICArIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xMikpICArIHRoZW1lKGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4KSkgKyBycmVtb3ZlKCJ5bGFiIikgKyBycmVtb3ZlKCJ4bGFiIiksIAogICAgICAgICAgICAgICAgICAgICAgICBBYlNjYXR0ZXIgICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSkgKyBycmVtb3ZlKCJ5bGFiIikgKyBycmVtb3ZlKCJ4bGFiIiksCiAgICAgICAgICAgICAgICAgICAgICAgIEN1U2NhdHRlciAgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTIpKSArIHJyZW1vdmUoInlsYWIiKSArIHJyZW1vdmUoInhsYWIiKSwKICAgICAgICAgICAgICAgICAgICAgICAgQ3BTY2F0dGVyICArIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xMikpICsgcnJlbW92ZSgieWxhYiIpICsgcnJlbW92ZSgieGxhYiIpLAogICAgICAgICAgICAgICAgICAgICAgICBDYlNjYXR0ZXIgICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSkgKyBycmVtb3ZlKCJ5bGFiIikgKyBycmVtb3ZlKCJ4bGFiIiksCiAgICAgICAgICAgICAgICAgICAgICAgIEN3U2NhdHRlciAgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTIpKSArIHJyZW1vdmUoInlsYWIiKSArIHJyZW1vdmUoInhsYWIiKSwKICAgICAgICAgIG5jb2wgPSAzLCBucm93ID0gMiwgY29tbW9uLmxlZ2VuZCA9IFQsIGxhYmVscyA9IE5VTEwsIGxlZ2VuZCA9ICJib3R0b20iLAogICAgICAgICAgYWxpZ24gPSAiaHYiLCAKICAgICAgICAgICAgICAgICAgICBmb250LmxhYmVsID0gbGlzdChzaXplID0gMTAsIGNvbG9yID0gImJsYWNrIiwgZmFjZSA9ICJib2xkIiwgZmFtaWx5ID0gTlVMTCwgcG9zaXRpb24gPSAidG9wIikpClBEUGFuZWwyIDwtIGFubm90YXRlX2ZpZ3VyZShQRFBhbmVsMiwgbGVmdCA9IHRleHRHcm9iKCJUaW1lIDIiLCByb3QgPSA5MCwgdmp1c3QgPSAxLCBoanVzdCA9IDAsIGdwID0gZ3BhcihjZXggPSAxKSksCiAgICAgICAgICAgICAgICAgICAgYm90dG9tID0gdGV4dEdyb2IoIlRpbWUgMSIsIHZqdXN0ID0gLTYuNSwgZ3AgPSBncGFyKGNleCA9IDEpKSkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSBjKDAsLTEpKQpQRFBhbmVsMgpnZ3NhdmUocGFzdGUwKHNhdmV0bywiUERQYW5lbC5qcGciKSxkcGk9NjAwKQpnZ3NhdmUocGFzdGUwKHNhdmV0bywiUERQYW5lbC50aWZmIiksZHBpPTYwMCkKYGBgCgojIFJlbGlhYmlsaXR5IE1ldGEtQW5hbHlzaXMKCmBgYHtyfQpkdCA8LSByZWFkLmNzdigifi9Eb2N1bWVudHMvR2l0SHViL01QVC1SZWxpYWJpbGl0eS9SZXRlc3Qvb3V0cHV0L2NvbWJRdWFkX0RmLmNzdiIpWzI6Nl0KCmR0JFBhcmFtW2R0JFBhcmFtPT0iRCJdPC0iRGV0ZWN0aW9uIgpkdCRQYXJhbVtkdCRQYXJhbT09Ik9CIl08LSJPdmVyY29taW5nIEJpYXMiCmR0JFBhcmFtW2R0JFBhcmFtPT0iQUNiYiJdPC0iQXNzb2NpYXRpb24gQmxhY2stQmFkIgpkdCRQYXJhbVtkdCRQYXJhbT09IkFDd2ciXTwtIkFzc29jaWF0aW9uIFdoaXRlLUdvb2QiCmR0JFBhcmFtW2R0JFBhcmFtPT0iRyJdPC0iR3Vlc3NpbmciCgpkdCRQYXJhbVtkdCRQYXJhbT09IlBJIl08LSJQcm9qZWN0IEltcGxpY2l0LCAyMDIwIgpkdCRQYXJhbVtkdCRQYXJhbT09IkNhbGFuY2hpbmkiXTwtIldpbHNvbiAmIENhbGFuY2hpbmksIDIwMjIiCmR0JFBhcmFtW2R0JFBhcmFtPT0iTGFpMSJdPC0iTGFpIGV0IGFsLiwgMjAxNiAoU3R1ZHkgMSkgICIKZHQkUGFyYW1bZHQkUGFyYW09PSJMYWkyIl08LSJMYWkgZXQgYWwuLCAyMDE2IChTdHVkeSAyKSAgIgpkdCRQYXJhbVtkdCRQYXJhbT09Ikdhd3JvbnNraSJdPC0iR2F3cm9uc2tpIGV0IGFsLiwgMjAxNyIKZHQkUGFyYW1bZHQkUGFyYW09PSJGb3JzY2hlciJdPC0iRm9yc2NoZXIgZXQgYWwuLCAyMDE3IgoKIyBpbmRlbnQgdGhlIHN1Ymdyb3VwIGlmIHRoZXJlIGlzIGEgbnVtYmVyIGluIHRoZSBwbGFjZWJvIGNvbHVtbgpkdCRQYXJhbSA8LSBpZmVsc2UoZHQkdHlwZT09MCwgCiAgICAgICAgICAgICAgICAgICAgICBkdCRQYXJhbSwKICAgICAgICAgICAgICAgICAgICAgIHBhc3RlMCgiICIsIGR0JFBhcmFtKSkKCmNvbG5hbWVzKGR0KVtjb2xuYW1lcyhkdCk9PSJQYXJhbSJdIDwtICIgICAiCmR0JGAgYCA8LSBwYXN0ZShyZXAoIiAiLCAyMCksIGNvbGxhcHNlID0gIiAiKQpkdCRgSUNDICg5NSUgQ0kpYCA8LSBpZmVsc2UoaXMubmEoZHQkSUNDKSwgIiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ByaW50ZigiJS4yZiBbJS4yZiwgJS4yZl0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHQkSUNDLCBkdCRDSS5MQiwgZHQkQ0kuVUIpKQoKCmR0JElDQ3N0dWR5IDwtIGlmZWxzZShkdCR0eXBlPT0xLCBkdCRJQ0MsIE5BKQpkdCRJQ0MuTEJzdHVkeSA8LSBpZmVsc2UoZHQkdHlwZT09MSwgZHQkQ0kuTEIsIE5BKQpkdCRJQ0MuVUJzdHVkeSA8LSBpZmVsc2UoZHQkdHlwZT09MSwgZHQkQ0kuVUIsIE5BKQpkdCRTaXplc3R1ZHkgPC0gaWZlbHNlKGR0JHR5cGU9PTEsIC42LCBOQSkKZHQkU2l6ZW1ldGEgPC0gaWZlbHNlKGR0JHR5cGU9PTAsIDEuMiwgTkEpCmR0JElDQ21ldGEgPC0gaWZlbHNlKGR0JHR5cGU9PTAsIGR0JElDQywgTkEpCmR0JElDQy5MQm1ldGEgPC0gaWZlbHNlKGR0JHR5cGU9PTAsIGR0JENJLkxCLCBOQSkKZHQkSUNDLlVCbWV0YSA8LSBpZmVsc2UoZHQkdHlwZT09MCwgZHQkQ0kuVUIsIE5BKQoKI2R0PC1kdFtjKDE6NCw2OjcpXQpkdDwtZHRbYygxOjQsNjpuY29sKGR0KSldCmNvbG5hbWVzKGR0KVtjb2xuYW1lcyhkdCk9PSJJQ0MgKDk1JSBDSSkiXSA8LSAiICAgICAiCgpsaWJyYXJ5KGZvcmVzdHBsb3RlcikKIyBwIDwtIGZvcmVzdCgKIyAgIGR0W2MoMSw1LDYpXSwKIyAgICAgICAgICAgICBlc3QgPSBkdCRJQ0MsCiMgICAgICAgICAgICAgbG93ZXIgPSBkdCRDSS5MQiwgCiMgICAgICAgICAgICAgdXBwZXIgPSBkdCRDSS5VQiwKIyAgICAgICAgICAgICBjaV9jb2x1bW4gPSAyLAojICAgICAgICAgICAgIHJlZl9saW5lID0gLjQsCiMgICAgICAgICAgICAgeGxpbSA9IGMoLS4xLCAxKSwKIyAgICAgICAgICAgICB0aWNrc19hdCA9IGMoMCwgLjQsLjYsIC43NSwgMSksCiMgICBzaXplcyA9IC4xCiMgKQoKdG0gPC0gZm9yZXN0X3RoZW1lKAogICAgICAgICAgICAgICAgICAgY2lfcGNoID0gYygxNSwgMTYpLAogICAgICAgICAgICAgICAgICAgY2lfY29sID0gYygiYmxhY2siLCJyZWQiKSwKICAgICAgICAgICAgICAgICAgIGNpX2x0eSA9IGMoICJzb2xpZCIsICJkYXNoZWQiKSwKICAgICAgICAgICAgICAgICAgIyBmb290bm90ZV9jb2wgPSAiYmx1ZSIsCiAgICAgICAgICAgICAgICAgICBsZWdlbmRfbmFtZSA9ICIgIiwKICAgICAgICAgICAgICAgICAgbGVnZW5kX3Bvc2l0aW9uID0gImJvdHRvbSIsCiAgICAgICAgICAgICAgICAgICBsZWdlbmRfdmFsdWUgPSBjKCJNZXRhLUFuYWx5c2lzICIsICJTdHVkeSIpCiAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICApCgpwIDwtIGZvcmVzdCgKICBkdFtjKDEsNSw2KV0sCiAgICAgICAgICAgIGVzdCA9IGxpc3QoZHQkSUNDbWV0YSwgZHQkSUNDc3R1ZHkpLAogICAgICAgICAgICBsb3dlciA9IGxpc3QoZHQkSUNDLkxCbWV0YSwgZHQkSUNDLkxCc3R1ZHkpLCAKICAgICAgICAgICAgdXBwZXIgPSBsaXN0KGR0JElDQy5VQm1ldGEsIGR0JElDQy5VQnN0dWR5KSwKICAgICAgICAgICAgICBjaV9jb2x1bW4gPSAyLAogICAgICAgICAgICByZWZfbGluZSA9IC40LAogICAgICAgICAgICB4bGltID0gYygtLjEsIDEpLAogICAgICAgICAgICB0aWNrc19hdCA9IGMoMCwgLjQsLjYsIC43NSwgMSksCiAgc2l6ZXMgPSBsaXN0KGR0JFNpemVtZXRhLCBkdCRTaXplc3R1ZHkpLAogIHRoZW1lID0gdG0KKQoKbGlicmFyeShncmlkKQpwIDwtIGVkaXRfcGxvdChwLAogICAgICAgICAgICAgICByb3cgPSBzZXEoZnJvbT0xLHRvPW5yb3coZHQpLGJ5PTcpLAogICAgICAgICAgICAgICBncCA9IGdwYXIoZm9udGZhY2UgPSBjKCJib2xkIiwiaXRhbGljIikKICAgICAgICAgICAgICAgICAgICAgICAgICksIGNvbCA9IDEpCgpzdHVkeUluZHMgPC0gc2V0ZGlmZigxOm5yb3coZHQpLHNlcShmcm9tPTEsdG89bnJvdyhkdCksYnk9NykpCnBhcmFtSW5kcyA8LSBzZXEoZnJvbT0xLHRvPW5yb3coZHQpLGJ5PTcpCgpwIDwtIGVkaXRfcGxvdChwLCByb3cgPSBzdHVkeUluZHMsIHdoaWNoID0gImJhY2tncm91bmQiLAogICAgICAgICAgICAgICBncCA9IGdwYXIoZmlsbCA9ICJ3aGl0ZSIpKQpwIDwtIGVkaXRfcGxvdChwLCByb3cgPSBwYXJhbUluZHMsIHdoaWNoID0gImJhY2tncm91bmQiLAogICAgICAgICAgICAgICBncCA9IGdwYXIoZmlsbCA9ICJncmV5IikpCgpgYGAKCgoKYGBge3J9CnBuZyhwYXN0ZTAoc2F2ZXRvLCJRdWFkX1RSVC5wbmciKSwgdW5pdHM9ImluIiwgd2lkdGg9MTAsIGhlaWdodD0xMiwgcmVzPTMwMCkKcGxvdChwKQpkZXYub2ZmKCkKYGBgCgoKYGBge3J9CiMgZ2dzYXZlIGZ1bmN0aW9uCmdncGxvdDI6Omdnc2F2ZShwYXN0ZTAoc2F2ZXRvLCJRdWFkX1RSVC5wbmciKSwKICAgICAgICAgICAgICAgIGRwaSA9IDMwMCwKICAgICAgICAgICAgICAgIHdpZHRoID0gNiwgaGVpZ2h0ID0gMTEsIHVuaXRzID0gImluIiwgcGxvdD1wKQoKZ2dwbG90Mjo6Z2dzYXZlKHBhc3RlMChzYXZldG8sIlF1YWRfVFJULnRpZmYiKSwKICAgICAgICAgICAgICAgIGRwaSA9IDYwMCwKICAgICAgICAgICAgICAgIHdpZHRoID0gNiwgaGVpZ2h0ID0gMTEsIHVuaXRzID0gImluIiwgcGxvdD1wKQpgYGAKCmBgYHtyfQpkdCA8LSByZWFkLmNzdigifi9Eb2N1bWVudHMvR2l0SHViL01QVC1SZWxpYWJpbGl0eS9SZXRlc3Qvb3V0cHV0L2NvbWJQRF9EZi5jc3YiKVsyOjZdCgpkdCRQYXJhbVtkdCRQYXJhbT09IkFiIl08LSJBdXRvbWF0aWMgQmxhY2siCmR0JFBhcmFtW2R0JFBhcmFtPT0iQXciXTwtIkF1dG9tYXRpYyBXaGl0ZSIKZHQkUGFyYW1bZHQkUGFyYW09PSJDYiJdPC0iQ29udHJvbCBCbGFjayIKZHQkUGFyYW1bZHQkUGFyYW09PSJDdyJdPC0iQ29udHJvbCBXaGl0ZSIKZHQkUGFyYW1bZHQkUGFyYW09PSJDdSJdPC0iQ29udHJvbCBCYWQiCmR0JFBhcmFtW2R0JFBhcmFtPT0iQ3AiXTwtIkNvbnRyb2wgR29vZCIKCmR0JFBhcmFtW2R0JFBhcmFtPT0iUEkiXTwtIlByb2plY3QgSW1wbGljaXQsIDIwMjAiCmR0JFBhcmFtW2R0JFBhcmFtPT0iQ2FsYW5jaGluaSJdPC0iV2lsc29uICYgQ2FsYW5jaGluaSwgMjAyMiIKZHQkUGFyYW1bZHQkUGFyYW09PSJMYWkxIl08LSJMYWkgZXQgYWwuLCAyMDE2IChTdHVkeSAxKSAgIgpkdCRQYXJhbVtkdCRQYXJhbT09IkxhaTIiXTwtIkxhaSBldCBhbC4sIDIwMTYgKFN0dWR5IDIpICAiCmR0JFBhcmFtW2R0JFBhcmFtPT0iR2F3cm9uc2tpIl08LSJHYXdyb25za2kgZXQgYWwuLCAyMDE3IgpkdCRQYXJhbVtkdCRQYXJhbT09IkZvcnNjaGVyIl08LSJGb3JzY2hlciBldCBhbC4sIDIwMTciCgojIGluZGVudCB0aGUgc3ViZ3JvdXAgaWYgdGhlcmUgaXMgYSBudW1iZXIgaW4gdGhlIHBsYWNlYm8gY29sdW1uCmR0JFBhcmFtIDwtIGlmZWxzZShkdCR0eXBlPT0wLCAKICAgICAgICAgICAgICAgICAgICAgIGR0JFBhcmFtLAogICAgICAgICAgICAgICAgICAgICAgcGFzdGUwKCIgIiwgZHQkUGFyYW0pKQoKY29sbmFtZXMoZHQpW2NvbG5hbWVzKGR0KT09IlBhcmFtIl0gPC0gIiAgICIKY29sbmFtZXMoZHQpW2NvbG5hbWVzKGR0KT09IlBhcmFtIl0gPC0gIiAgICIKZHQkYCBgIDwtIHBhc3RlKHJlcCgiICIsIDIwKSwgY29sbGFwc2UgPSAiICIpCmR0JGBJQ0MgKDk1JSBDSSlgIDwtIGlmZWxzZShpcy5uYShkdCRJQ0MpLCAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcHJpbnRmKCIlLjJmIFslLjJmLCAlLjJmXSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkdCRJQ0MsIGR0JENJLkxCLCBkdCRDSS5VQikpCgpkdCRJQ0NzdHVkeSA8LSBpZmVsc2UoZHQkdHlwZT09MSwgZHQkSUNDLCBOQSkKZHQkSUNDLkxCc3R1ZHkgPC0gaWZlbHNlKGR0JHR5cGU9PTEsIGR0JENJLkxCLCBOQSkKZHQkSUNDLlVCc3R1ZHkgPC0gaWZlbHNlKGR0JHR5cGU9PTEsIGR0JENJLlVCLCBOQSkKZHQkU2l6ZXN0dWR5IDwtIGlmZWxzZShkdCR0eXBlPT0xLCAuNiwgTkEpCmR0JFNpemVtZXRhIDwtIGlmZWxzZShkdCR0eXBlPT0wLCAxLjIsIE5BKQpkdCRJQ0NtZXRhIDwtIGlmZWxzZShkdCR0eXBlPT0wLCBkdCRJQ0MsIE5BKQpkdCRJQ0MuTEJtZXRhIDwtIGlmZWxzZShkdCR0eXBlPT0wLCBkdCRDSS5MQiwgTkEpCmR0JElDQy5VQm1ldGEgPC0gaWZlbHNlKGR0JHR5cGU9PTAsIGR0JENJLlVCLCBOQSkKCiNkdDwtZHRbYygxOjQsNjo3KV0KZHQ8LWR0W2MoMTo0LDY6bmNvbChkdCkpXQpjb2xuYW1lcyhkdClbY29sbmFtZXMoZHQpPT0iSUNDICg5NSUgQ0kpIl0gPC0gIiAgICAgIgoKbGlicmFyeShmb3Jlc3RwbG90ZXIpCiMgcCA8LSBmb3Jlc3QoCiMgICBkdFtjKDEsNSw2KV0sCiMgICAgICAgICAgICAgZXN0ID0gZHQkSUNDLAojICAgICAgICAgICAgIGxvd2VyID0gZHQkQ0kuTEIsIAojICAgICAgICAgICAgIHVwcGVyID0gZHQkQ0kuVUIsCiMgICAgICAgICAgICAgY2lfY29sdW1uID0gMiwKIyAgICAgICAgICAgICByZWZfbGluZSA9IC40LAojICAgICAgICAgICAgIHhsaW0gPSBjKC0uMSwgMSksCiMgICAgICAgICAgICAgdGlja3NfYXQgPSBjKDAsIC40LC42LCAuNzUsIDEpLAojICAgc2l6ZXMgPSAuMQojICkKCnRtIDwtIGZvcmVzdF90aGVtZSgKICAgICAgICAgICAgICAgICAgIGNpX3BjaCA9IGMoMTUsIDE2KSwKICAgICAgICAgICAgICAgICAgIGNpX2NvbCA9IGMoImJsYWNrIiwicmVkIiksCiAgICAgICAgICAgICAgICAgICBjaV9sdHkgPSBjKCAic29saWQiLCAiZGFzaGVkIiksCiAgICAgICAgICAgICAgICAgICMgZm9vdG5vdGVfY29sID0gImJsdWUiLAogICAgICAgICAgICAgICAgICAgbGVnZW5kX25hbWUgPSAiICIsCiAgICAgICAgICAgICAgICAgIGxlZ2VuZF9wb3NpdGlvbiA9ICJib3R0b20iLAogICAgICAgICAgICAgICAgICAgbGVnZW5kX3ZhbHVlID0gYygiTWV0YS1BbmFseXNpcyAiLCAiU3R1ZHkiKQogICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgKQoKcCA8LSBmb3Jlc3QoCiAgZHRbYygxLDUsNildLAogICAgICAgICAgICBlc3QgPSBsaXN0KGR0JElDQ21ldGEsIGR0JElDQ3N0dWR5KSwKICAgICAgICAgICAgbG93ZXIgPSBsaXN0KGR0JElDQy5MQm1ldGEsIGR0JElDQy5MQnN0dWR5KSwgCiAgICAgICAgICAgIHVwcGVyID0gbGlzdChkdCRJQ0MuVUJtZXRhLCBkdCRJQ0MuVUJzdHVkeSksCiAgICAgICAgICAgICAgY2lfY29sdW1uID0gMiwKICAgICAgICAgICAgcmVmX2xpbmUgPSAuNCwKICAgICAgICAgICAgeGxpbSA9IGMoLS4xLCAxKSwKICAgICAgICAgICAgdGlja3NfYXQgPSBjKDAsIC40LC42LCAuNzUsIDEpLAogIHNpemVzID0gbGlzdChkdCRTaXplbWV0YSwgZHQkU2l6ZXN0dWR5KSwKICB0aGVtZSA9IHRtCikKCmxpYnJhcnkoZ3JpZCkKcCA8LSBlZGl0X3Bsb3QocCwKICAgICAgICAgICAgICAgcm93ID0gc2VxKGZyb209MSx0bz1ucm93KGR0KSxieT03KSwKICAgICAgICAgICAgICAgZ3AgPSBncGFyKGZvbnRmYWNlID0gYygiYm9sZCIsIml0YWxpYyIpCiAgICAgICAgICAgICAgICAgICAgICAgICApLCBjb2wgPSAxKQoKc3R1ZHlJbmRzIDwtIHNldGRpZmYoMTpucm93KGR0KSxzZXEoZnJvbT0xLHRvPW5yb3coZHQpLGJ5PTcpKQpwYXJhbUluZHMgPC0gc2VxKGZyb209MSx0bz1ucm93KGR0KSxieT03KQoKcCA8LSBlZGl0X3Bsb3QocCwgcm93ID0gc3R1ZHlJbmRzLCB3aGljaCA9ICJiYWNrZ3JvdW5kIiwKICAgICAgICAgICAgICAgZ3AgPSBncGFyKGZpbGwgPSAid2hpdGUiKSkKcCA8LSBlZGl0X3Bsb3QocCwgcm93ID0gcGFyYW1JbmRzLCB3aGljaCA9ICJiYWNrZ3JvdW5kIiwKICAgICAgICAgICAgICAgZ3AgPSBncGFyKGZpbGwgPSAiZ3JleSIpKQoKYGBgCgoKCmBgYHtyfQpwbmcocGFzdGUwKHNhdmV0bywiUERQX1RSVC5wbmciKSwgdW5pdHM9ImluIiwgd2lkdGg9MTAsIGhlaWdodD0xNSwgcmVzPTMwMCkKcGxvdChwKQpkZXYub2ZmKCkKYGBgCgpgYGB7cn0KIyBnZ3NhdmUgZnVuY3Rpb24KZ2dwbG90Mjo6Z2dzYXZlKHBhc3RlMChzYXZldG8sIlBEUF9UUlQucG5nIiksCiAgICAgICAgICAgICAgICBkcGkgPSAzMDAsCiAgICAgICAgICAgICAgICB3aWR0aCA9IDYsIGhlaWdodCA9IDEzLCB1bml0cyA9ICJpbiIsIHBsb3Q9cCkKCmdncGxvdDI6Omdnc2F2ZShwYXN0ZTAoc2F2ZXRvLCJQRFBfVFJULnRpZmYiKSwKICAgICAgICAgICAgICAgIGRwaSA9IDYwMCwKICAgICAgICAgICAgICAgIHdpZHRoID0gNiwgaGVpZ2h0ID0gMTMsIHVuaXRzID0gImluIiwgcGxvdD1wKQpgYGAKCgojIFJlY292ZXJ5CgpgYGB7cn0Kc2V0d2QocGFzdGUwKCIvVm9sdW1lcy9SZXNlYXJjaCBQcm9qZWN0L0lBVF9SZXRlc3QvUmVjb3ZlcnkvUmVjb3ZlcmVkUGFyYW1zL1BELyIpKQp0aW1lczwtYygiVGltZTEiLCJUaW1lMiIpCgphbGxyZWNvdnMgPC0gYXMuZGF0YS5mcmFtZShtYXRyaXgobmNvbD0xNCxucm93PTApKQoKUERkaXJzIDwtIGxpc3QuZGlycyhwYXRoID0gIi4iLCBmdWxsLm5hbWVzID0gVFJVRSwgcmVjdXJzaXZlID0gVFJVRSlbLTFdCmZvcihkIGluIFBEZGlycyl7CiAgZm9yKHRpIGluIHRpbWVzKXsKICAgIGN1ckZpbGVzIDwtIGxpc3QuZmlsZXMocGF0aD1kLHBhdHRlcm49IlxcLmNzdiQiKQogICAgaWQ8LWdyZXAodGksY3VyRmlsZXMpCiAgICBvdXRwdXQ8LXJlYWQuY3N2KHBhc3RlMChkLCIvIixjdXJGaWxlc1tpZF0pKQogICAgbmFtZTwtZ3N1YigiLi8iLCIiLGQpCiAgICBuYW1lPC1nc3ViKCIgIiwiIixuYW1lKQogICAgCiAgICBpZih0aT09IlRpbWUxIil7CiAgICAgICNjb2xuYW1lcyhvdXRwdXQpIDwtIHBhc3RlKGNvbG5hbWVzKG91dHB1dCksIlQxIixzZXA9Il8iKQogICAgICBvdXRwdXQkdGltZSA8LSAiVDEiCiAgICB9ZWxzZSBpZih0aT09IlRpbWUyIil7CiAgICAgICNjb2xuYW1lcyhvdXRwdXQpIDwtIHBhc3RlKGNvbG5hbWVzKG91dHB1dCksIlQyIixzZXA9Il8iKQogICAgICBvdXRwdXQkdGltZSA8LSAiVDIiCiAgICB9CiAgICAKICAgIGFzc2lnbihwYXN0ZTAobmFtZSwiLlBELlJlY292LiIsdGkpLG91dHB1dCkKICB9CiAgZGYgPC0gcmJpbmQoZ2V0KHBhc3RlMChuYW1lLCIuUEQuUmVjb3YuVGltZTEiKSksZ2V0KHBhc3RlMChuYW1lLCIuUEQuUmVjb3YuVGltZTIiKSkpCiAgYXNzaWduKHBhc3RlMChuYW1lLCIuUEQuUmVjb3YiKSxkZikKICBhbGxyZWNvdnMgPC0gcmJpbmQoYWxscmVjb3ZzLGNiaW5kKGRmLFN0dWR5PW5hbWUpKQp9CgoKYWxscmVjb3ZzJFN0dWR5IDwtIGdzdWIoIkxhaTEiLCAiTGFpIDEiLCBhbGxyZWNvdnMkU3R1ZHkpCmFsbHJlY292cyRTdHVkeSA8LSBnc3ViKCJMYWkyIiwgIkxhaSAyIiwgYWxscmVjb3ZzJFN0dWR5KQpQRC5yZWNvdnMgPC0gYWxscmVjb3ZzClBELnJlY292cyA8LSBkcGx5cjo6cmVuYW1lKFBELnJlY292cywgc3ViSUQ9WCkKCnRhcHBseShQRC5yZWNvdnMkQWIxLCBQRC5yZWNvdnMkU3R1ZHksIGZ1bmN0aW9uKHgpIGxlbmd0aCh4KSkKYGBgCgpgYGB7cn0KcGF0aCA8LSAiL1ZvbHVtZXMvIgpzZXR3ZChwYXN0ZTAocGF0aCwiUmVzZWFyY2ggUHJvamVjdC9JQVRfUmV0ZXN0L0VzdGltYXRlcy9VQ1IvIikpCkNhbDEgPC1yZWFkLmNzdigiSW5kaXZpZHVhbFBhcmFtZXRlcnNQRFVDUjEuY3N2IiwgaGVhZGVyID0gVCkKQ2FsMiA8LXJlYWQuY3N2KCJJbmRpdmlkdWFsUGFyYW1ldGVyc1BEVUNSMi5jc3YiLCBoZWFkZXIgPSBUKQoKQ2FsMSR0aW1lIDwtICJUMSIKQ2FsMiR0aW1lIDwtICJUMiIKQ2FsMSRzdWJJRCA8LSAxOm5yb3coQ2FsMSkKQ2FsMiRzdWJJRCA8LSAxOm5yb3coQ2FsMikKUC5DYWwgPC0gcmJpbmQoQ2FsMSwgQ2FsMikKCnNldHdkKHBhc3RlMChwYXRoLCJSZXNlYXJjaCBQcm9qZWN0L0lBVF9SZXRlc3QvRXN0aW1hdGVzL1BJLyIpKQpQSTEgPC0gcmVhZC5jc3YoIkluZGl2aWR1YWxQYXJhbWV0ZXJzUHJvamVjdEltcGxpY2l0UEQxLmNzdiIpClBJMiA8LSByZWFkLmNzdigiSW5kaXZpZHVhbFBhcmFtZXRlcnNQcm9qZWN0SW1wbGljaXRQRDIuY3N2IikKClBJMSR0aW1lIDwtICJUMSIKUEkyJHRpbWUgPC0gIlQyIgpQSTEkc3ViSUQgPC0gMTpucm93KFBJMSkKUEkyJHN1YklEIDwtIDE6bnJvdyhQSTIpClAuUEkgPC0gcmJpbmQoUEkxLCBQSTIpCgpzZXR3ZChwYXN0ZTAocGF0aCwiUmVzZWFyY2ggUHJvamVjdC9JQVRfUmV0ZXN0L0VzdGltYXRlcy9HYXdyb25za2kvIikpCkdhdzEgPC0gcmVhZC5jc3YoIkluZGl2aWR1YWxQYXJhbWV0ZXJzUERHYXdyb25za2kxLmNzdiIpCkdhdzIgPC0gcmVhZC5jc3YoIkluZGl2aWR1YWxQYXJhbWV0ZXJzUERHYXdyb25za2kyLmNzdiIpCgpHYXcxJHRpbWUgPC0gIlQxIgpHYXcyJHRpbWUgPC0gIlQyIgpHYXcxJHN1YklEIDwtIDE6bnJvdyhHYXcxKQpHYXcyJHN1YklEIDwtIDE6bnJvdyhHYXcyKQpQLkdhdyA8LSByYmluZChHYXcxLCBHYXcyKQoKc2V0d2QocGFzdGUwKHBhdGgsIlJlc2VhcmNoIFByb2plY3QvSUFUX1JldGVzdC9Fc3RpbWF0ZXMvRm9yc2NoZXIvIikpCkZvcjE8LXJlYWQuY3N2KCJJbmRpdmlkdWFsUGFyYW1ldGVyc0ZvcnNjaGVyUEQxLmNzdiIsIGhlYWRlciA9IFQpCkZvcjI8LXJlYWQuY3N2KCJJbmRpdmlkdWFsUGFyYW1ldGVyc0ZvcnNjaGVyUEQyLmNzdiIsIGhlYWRlciA9IFQpCgpGb3IxJHRpbWUgPC0gIlQxIgpGb3IyJHRpbWUgPC0gIlQyIgpGb3IxJHN1YklEIDwtIDE6bnJvdyhGb3IxKQpGb3IyJHN1YklEIDwtIDE6bnJvdyhGb3IyKQpQLkZvciA8LSByYmluZChGb3IxLCBGb3IyKQoKc2V0d2QocGFzdGUwKHBhdGgsIlJlc2VhcmNoIFByb2plY3QvSUFUX1JldGVzdC9Fc3RpbWF0ZXMvTGFpMS8iKSkKTGFpMTE8LXJlYWQuY3N2KCJJbmRpdmlkdWFsUGFyYW1ldGVyc0xhaVN0dWR5MVBEMS5jc3YiLCBoZWFkZXIgPSBUKQpMYWkxMjwtcmVhZC5jc3YoIkluZGl2aWR1YWxQYXJhbWV0ZXJzTGFpU3R1ZHkxUEQyLmNzdiIsIGhlYWRlciA9IFQpCgpMYWkxMSR0aW1lIDwtICJUMSIKTGFpMTIkdGltZSA8LSAiVDIiCkxhaTExJHN1YklEIDwtIDE6bnJvdyhMYWkxMSkKTGFpMTIkc3ViSUQgPC0gMTpucm93KExhaTEyKQpQLkxhaTEgPC0gcmJpbmQoTGFpMTEsIExhaTEyKQoKc2V0d2QocGFzdGUwKHBhdGgsIlJlc2VhcmNoIFByb2plY3QvSUFUX1JldGVzdC9Fc3RpbWF0ZXMvTGFpMi8iKSkKTGFpMjE8LXJlYWQuY3N2KCJJbmRpdmlkdWFsUGFyYW1ldGVyc0xhaVN0dWR5MlBEMS5jc3YiLCBoZWFkZXIgPSBUKQpMYWkyMjwtcmVhZC5jc3YoIkluZGl2aWR1YWxQYXJhbWV0ZXJzTGFpU3R1ZHkyUEQyLmNzdiIsIGhlYWRlciA9IFQpCgpMYWkyMSR0aW1lIDwtICJUMSIKTGFpMjIkdGltZSA8LSAiVDIiCkxhaTIxJHN1YklEIDwtIDE6bnJvdyhMYWkyMSkKTGFpMjIkc3ViSUQgPC0gMTpucm93KExhaTIyKQpQLkxhaTIgPC0gcmJpbmQoTGFpMjEsTGFpMjIpCgpjb2xuYW1lcyhQLkNhbClbMV0gPC0gInN1YklEIgpQLkNhbCA8LSBjYmluZChQLkNhbCwgU3R1ZHkgPSAiQ2FsYW5jaGluaSIpCmNvbG5hbWVzKFAuUEkpWzFdIDwtICJzdWJJRCIKUC5QSSA8LSBjYmluZChQLlBJLCBTdHVkeSA9ICJQSSIpCmNvbG5hbWVzKFAuR2F3KVsxXSA8LSAic3ViSUQiClAuR2F3IDwtIGNiaW5kKFAuR2F3LCBTdHVkeSA9ICJHYXdyb25za2kiKQpjb2xuYW1lcyhQLkZvcilbMV0gPC0gInN1YklEIgpQLkZvciA8LSBjYmluZChQLkZvciwgU3R1ZHkgPSAiRm9yc2NoZXIiKQpjb2xuYW1lcyhQLkxhaTEpWzFdIDwtICJzdWJJRCIKUC5MYWkxIDwtIGNiaW5kKFAuTGFpMSwgU3R1ZHkgPSAiTGFpIDEiKQpjb2xuYW1lcyhQLkxhaTIpWzFdIDwtICJzdWJJRCIKUC5MYWkyIDwtIGNiaW5kKFAuTGFpMiwgU3R1ZHkgPSAiTGFpIDIiKQoKUEQub3JpZyA8LSByYmluZChQLkNhbCxQLlBJLFAuR2F3LFAuRm9yLFAuTGFpMSxQLkxhaTIpClBELm9yaWdbMV0gPC0gTlVMTApgYGAKCmBgYHtyfQoKY29sbmFtZXMoUEQucmVjb3ZzKVsyOiAobmNvbChQRC5yZWNvdnMpLTIpIF0gPC0gcGFzdGUoY29sbmFtZXMoUEQucmVjb3ZzKVsyOiAobmNvbChQRC5yZWNvdnMpLTIpIF0sIlIiLHNlcD0iXyIpCmNvbG5hbWVzKFBELm9yaWcpWzE6IChuY29sKFBELm9yaWcpLTMpIF0gPC0gcGFzdGUoY29sbmFtZXMoUEQub3JpZylbMTogKG5jb2woUEQub3JpZyktMykgXSwiTyIsc2VwPSJfIikKUEQub3JpZyA8LSBQRC5vcmlnW29yZGVyKFBELm9yaWckU3R1ZHksIFBELm9yaWckdGltZSksXQpQRC5yZWNvdnMgPC0gUEQucmVjb3ZzW29yZGVyKFBELnJlY292cyRTdHVkeSwgUEQucmVjb3ZzJHRpbWUpLF0KCiNQRC5vcmlnLnJlY292cyA8LSBjYmluZChQRC5vcmlnLFBELnJlY292cykKUEQub3JpZy5yZWNvdnMgPC0gbWVyZ2UoUEQub3JpZywgUEQucmVjb3ZzLCBieSA9IGMoInN1YklEIiwiU3R1ZHkiLCJ0aW1lIikpCgpQRC5vcmlnLnJlY292cyRTdHVkeVtQRC5vcmlnLnJlY292cyRTdHVkeT09IlBJIl08LSJQcm9qZWN0IEltcGxpY2l0LCAyMDIwIgpQRC5vcmlnLnJlY292cyRTdHVkeVtQRC5vcmlnLnJlY292cyRTdHVkeT09IkNhbGFuY2hpbmkiXTwtIldpbHNvbiAmIENhbGFuY2hpbmksIDIwMjIiClBELm9yaWcucmVjb3ZzJFN0dWR5W1BELm9yaWcucmVjb3ZzJFN0dWR5PT0iTGFpIDEiXTwtIkxhaSBldCBhbC4sIDIwMTYgKFN0dWR5IDEpICAiClBELm9yaWcucmVjb3ZzJFN0dWR5W1BELm9yaWcucmVjb3ZzJFN0dWR5PT0iTGFpIDIiXTwtIkxhaSBldCBhbC4sIDIwMTYgKFN0dWR5IDIpICAiClBELm9yaWcucmVjb3ZzJFN0dWR5W1BELm9yaWcucmVjb3ZzJFN0dWR5PT0iR2F3cm9uc2tpIl08LSJHYXdyb25za2kgZXQgYWwuLCAyMDE3IgpQRC5vcmlnLnJlY292cyRTdHVkeVtQRC5vcmlnLnJlY292cyRTdHVkeT09IkZvcnNjaGVyIl08LSJGb3JzY2hlciBldCBhbC4sIDIwMTciCmBgYAoKCiMgUmVjb3ZlcnkKCiMjIFBEIE1vZGVsCgojIyMgQXV0b21hdGljIEJsYWNrCgpgYGB7cn0KQWJTY2F0dGVyIDwtIGdncGxvdChQRC5vcmlnLnJlY292cywgYWVzKHg9QWIxX08sIHk9QWIxX1IsIGNvbG9yPVN0dWR5LCBzaGFwZT10aW1lKSkgKyAKICBnZW9tX3BvaW50KGFscGhhID0gLjIpKwogIGdlb21fc21vb3RoKG1ldGhvZD1sbSwgc2U9VFJVRSwgbGluZXR5cGUgPSAiZGFzaGVkIiwKICAgICAgICAgICAgIGNvbG9yPSJncmV5IikgICsgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0ID0gMCwgc2xvcGUgPSAxKSArIHlsaW0oMCwxKSArIHhsaW0oMCwxKSArIGxhYnModGl0bGU9IkF1dG9tYXRpYyBCbGFjayIsCiAgICAgICB4PSJPcmlnaW5hbCIsIHkgPSAiUmVjb3ZlcmVkIikgKyBndWlkZXMoY29sb3VyID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3QoYWxwaGEgPSAxKSkpICsKICBqdG9vbHM6OnRoZW1lX2FwYSgpCgpBYlNjYXR0ZXIKZ2dzYXZlKHBhc3RlMChzYXZldG8sIkFiU2NhdHRlclJFQy5qcGciKSxkcGk9NjAwKQpnZ3NhdmUocGFzdGUwKHNhdmV0bywiQWJTY2F0dGVyUkVDLnRpZmYiKSxkcGk9NjAwKQpgYGAKCiMjIyBBdXRvbWF0aWMgV2hpdGUKCmBgYHtyfQpBd1NjYXR0ZXIgPC0gZ2dwbG90KFBELm9yaWcucmVjb3ZzLCBhZXMoeD1BdzFfTywgeT1BdzFfUiwgY29sb3I9U3R1ZHksIHNoYXBlPXRpbWUpKSArIAogIGdlb21fcG9pbnQoYWxwaGEgPSAuMikrCiAgZ2VvbV9zbW9vdGgobWV0aG9kPWxtLCBzZT1UUlVFLCBsaW5ldHlwZT0iZGFzaGVkIiwKICAgICAgICAgICAgIGNvbG9yPSJncmV5IikgICsgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0ID0gMCwgc2xvcGUgPSAxKSArIHlsaW0oMCwxKSArIHhsaW0oMCwxKSArIGxhYnModGl0bGU9IkF1dG9tYXRpYyBXaGl0ZSIsCiAgICAgICB4PSJPcmlnaW5hbCIsIHkgPSAiUmVjb3ZlcmVkIikgKyBndWlkZXMoY29sb3VyID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3QoYWxwaGEgPSAxKSkpICsKICBqdG9vbHM6OnRoZW1lX2FwYSgpCkF3U2NhdHRlcgpnZ3NhdmUocGFzdGUwKHNhdmV0bywiQXdTY2F0dGVyUkVDLmpwZyIpLGRwaT02MDApCmdnc2F2ZShwYXN0ZTAoc2F2ZXRvLCJBd1NjYXR0ZXJSRUMudGlmZiIpLGRwaT02MDApCmBgYAoKIyMjIENvbnRyb2wgR29vZAoKYGBge3J9CkNwU2NhdHRlciA8LSBnZ3Bsb3QoUEQub3JpZy5yZWNvdnMsIGFlcyh4PUNwMV9PLCB5PUNwMV9SLCBjb2xvcj1TdHVkeSwgc2hhcGU9dGltZSkpICsgCiAgZ2VvbV9wb2ludChhbHBoYSA9IC4yKSsKICBnZW9tX3Ntb290aChtZXRob2Q9bG0sIHNlPVRSVUUsIGxpbmV0eXBlPSJkYXNoZWQiLAogICAgICAgICAgICAgY29sb3I9ImdyZXkiKSAgKyBnZW9tX2FibGluZShpbnRlcmNlcHQgPSAwLCBzbG9wZSA9IDEpICsgeWxpbSgwLDEpICsgeGxpbSgwLDEpICsgbGFicyh0aXRsZT0iQ29udHJvbCBHb29kIiwKICAgICAgIHg9Ik9yaWdpbmFsIiwgeSA9ICJSZWNvdmVyZWQiKSArIGd1aWRlcyhjb2xvdXIgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChhbHBoYSA9IDEpKSkgKwogIGp0b29sczo6dGhlbWVfYXBhKCkKQ3BTY2F0dGVyCmdnc2F2ZShwYXN0ZTAoc2F2ZXRvLCJDcFNjYXR0ZXJSRUMuanBnIiksZHBpPTYwMCkKZ2dzYXZlKHBhc3RlMChzYXZldG8sIkF3U2NhdHRlclJFQy50aWZmIiksZHBpPTYwMCkKYGBgCgojIyMgQ29udHJvbCBCYWQKCmBgYHtyfQpDdVNjYXR0ZXIgPC0gZ2dwbG90KFBELm9yaWcucmVjb3ZzLCBhZXMoeD1DdTFfTywgeT1DdTFfUiwgY29sb3I9U3R1ZHksIHNoYXBlPXRpbWUpKSArIAogIGdlb21fcG9pbnQoYWxwaGEgPSAuMikrCiAgZ2VvbV9zbW9vdGgobWV0aG9kPWxtLCBzZT1UUlVFLCBsaW5ldHlwZT0iZGFzaGVkIiwKICAgICAgICAgICAgIGNvbG9yPSJncmV5IikgICsgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0ID0gMCwgc2xvcGUgPSAxKSArIHlsaW0oMCwxKSArIHhsaW0oMCwxKSArIGxhYnModGl0bGU9IkNvbnRyb2wgQmFkIiwKICAgICAgIHg9Ik9yaWdpbmFsIiwgeSA9ICJSZWNvdmVyZWQiKSArIGd1aWRlcyhjb2xvdXIgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChhbHBoYSA9IDEpKSkgKwogIGp0b29sczo6dGhlbWVfYXBhKCkKQ3VTY2F0dGVyCmdnc2F2ZShwYXN0ZTAoc2F2ZXRvLCJDdVNjYXR0ZXJSRUMuanBnIiksZHBpPTYwMCkKZ2dzYXZlKHBhc3RlMChzYXZldG8sIkN1U2NhdHRlclJFQy50aWZmIiksZHBpPTYwMCkKYGBgCgojIyMgQ29udHJvbCBXaGl0ZQoKYGBge3J9CkN3U2NhdHRlciA8LSBnZ3Bsb3QoUEQub3JpZy5yZWNvdnMsIGFlcyh4PUN3MV9PLCB5PUN3MV9SLCBjb2xvcj1TdHVkeSwgc2hhcGU9dGltZSkpICsgCiAgZ2VvbV9wb2ludChhbHBoYSA9IC4yKSsKICBnZW9tX3Ntb290aChtZXRob2Q9bG0sIHNlPVRSVUUsIGxpbmV0eXBlPSJkYXNoZWQiLAogICAgICAgICAgICAgY29sb3I9ImdyZXkiKSAgKyBnZW9tX2FibGluZShpbnRlcmNlcHQgPSAwLCBzbG9wZSA9IDEpICsgeWxpbSgwLDEpICsgeGxpbSgwLDEpICsgbGFicyh0aXRsZT0iQ29udHJvbCBXaGl0ZSIsCiAgICAgICB4PSJPcmlnaW5hbCIsIHkgPSAiUmVjb3ZlcmVkIikgKyBndWlkZXMoY29sb3VyID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3QoYWxwaGEgPSAxKSkpICsKICBqdG9vbHM6OnRoZW1lX2FwYSgpCkN3U2NhdHRlcgpnZ3NhdmUocGFzdGUwKHNhdmV0bywiQ3dTY2F0dGVyUkVDLmpwZyIpLGRwaT02MDApCmdnc2F2ZShwYXN0ZTAoc2F2ZXRvLCJDd1NjYXR0ZXJSRUMudGlmZiIpLGRwaT02MDApCmBgYAoKIyMjIENvbnRyb2wgQmxhY2sKCmBgYHtyfQpDYlNjYXR0ZXIgPC0gZ2dwbG90KFBELm9yaWcucmVjb3ZzLCBhZXMoeD1DYjFfTywgeT1DYjFfUiwgY29sb3I9U3R1ZHksIHNoYXBlPXRpbWUpKSArIAogIGdlb21fcG9pbnQoYWxwaGEgPSAuMikrCiAgZ2VvbV9zbW9vdGgobWV0aG9kPWxtLCBzZT1UUlVFLCBsaW5ldHlwZT0iZGFzaGVkIiwKICAgICAgICAgICAgIGNvbG9yPSJncmV5IikgICsgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0ID0gMCwgc2xvcGUgPSAxKSArIHlsaW0oMCwxKSArIHhsaW0oMCwxKSArIGxhYnModGl0bGU9IkNvbnRyb2wgQmxhY2siLAogICAgICAgeD0iT3JpZ2luYWwiLCB5ID0gIlJlY292ZXJlZCIpICsgZ3VpZGVzKGNvbG91ciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KGFscGhhID0gMSkpKSArCiAganRvb2xzOjp0aGVtZV9hcGEoKQpDYlNjYXR0ZXIKZ2dzYXZlKHBhc3RlMChzYXZldG8sIkNiU2NhdHRlclJFQy5qcGciKSxkcGk9NjAwKQpnZ3NhdmUocGFzdGUwKHNhdmV0bywiQ2JTY2F0dGVyUkVDLnRpZmYiKSxkcGk9NjAwKQpgYGAKCiMjIyBQYW5lbAoKYGBge3J9CmxpYnJhcnkoZ2dwdWJyKQpQRFBhbmVsMSA8LSBnZ2FycmFuZ2UoQXdTY2F0dGVyLCBBYlNjYXR0ZXIsIEN1U2NhdHRlciwgQ3BTY2F0dGVyLCBDYlNjYXR0ZXIsIEN3U2NhdHRlciwKICAgICAgICAgIG5jb2wgPSAzLCBucm93ID0gMiwgY29tbW9uLmxlZ2VuZCA9IFQpClBEUGFuZWwxCgpyZXF1aXJlKGdyaWQpICAgIyBmb3IgdGhlIHRleHRHcm9iKCkgZnVuY3Rpb24KClBEUGFuZWwyIDwtIGdnYXJyYW5nZShBd1NjYXR0ZXIgICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSkgKyB0aGVtZShsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCkpICsgcnJlbW92ZSgieWxhYiIpICsgcnJlbW92ZSgieGxhYiIpLCAKICAgICAgICAgICAgICAgICAgICAgICAgQWJTY2F0dGVyICArIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xMikpICsgcnJlbW92ZSgieWxhYiIpICsgcnJlbW92ZSgieGxhYiIpLAogICAgICAgICAgICAgICAgICAgICAgICBDdVNjYXR0ZXIgICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSkgKyBycmVtb3ZlKCJ5bGFiIikgKyBycmVtb3ZlKCJ4bGFiIiksCiAgICAgICAgICAgICAgICAgICAgICAgIENwU2NhdHRlciAgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTIpKSArIHJyZW1vdmUoInlsYWIiKSArIHJyZW1vdmUoInhsYWIiKSwKICAgICAgICAgICAgICAgICAgICAgICAgQ2JTY2F0dGVyICArIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xMikpICsgcnJlbW92ZSgieWxhYiIpICsgcnJlbW92ZSgieGxhYiIpLAogICAgICAgICAgICAgICAgICAgICAgICBDd1NjYXR0ZXIgICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSkgKyBycmVtb3ZlKCJ5bGFiIikgKyBycmVtb3ZlKCJ4bGFiIiksCiAgICAgICAgICBuY29sID0gMywgbnJvdyA9IDIsIGNvbW1vbi5sZWdlbmQgPSBULCBsYWJlbHMgPSBOVUxMLCBsZWdlbmQgPSBjKCJib3R0b20iKSwKICAgICAgICAgIGFsaWduID0gImh2IiwgCiAgICAgICAgICAgICAgICAgICAgZm9udC5sYWJlbCA9IGxpc3Qoc2l6ZSA9IDEwLCBjb2xvciA9ICJibGFjayIsIGZhY2UgPSAiYm9sZCIsIGZhbWlseSA9IE5VTEwsIHBvc2l0aW9uID0gInRvcCIpKQoKUERQYW5lbDIgPC0gYW5ub3RhdGVfZmlndXJlKFBEUGFuZWwyLCBsZWZ0ID0gdGV4dEdyb2IoIlJlY292ZXJlZCIsIHJvdCA9IDkwLCB2anVzdCA9IDEsIGhqdXN0ID0gMCwgZ3AgPSBncGFyKGNleCA9IDEpKSwKICAgICAgICAgICAgICAgICAgICBib3R0b20gPSB0ZXh0R3JvYigiT3JpZ2luYWwiLCB2anVzdCA9IC02LjUsIGdwID0gZ3BhcihjZXggPSAxKSkpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gYygwLC0xKSkKUERQYW5lbDIKZ2dzYXZlKHBhc3RlMChzYXZldG8sIlBEUGFuZWxSRUMuanBnIiksZHBpPTYwMCkKZ2dzYXZlKHBhc3RlMChzYXZldG8sIlBEUGFuZWxSRUMudGlmZiIpLGRwaT02MDApCmBgYAoKIyMgUXVhZCBNb2RlbAoKIyBSZWNvdmVyeQoKYGBge3J9CnNldHdkKHBhc3RlMCgiL1ZvbHVtZXMvUmVzZWFyY2ggUHJvamVjdC9JQVRfUmV0ZXN0L1JlY292ZXJ5L1JlY292ZXJlZFBhcmFtcy9RdWFkLyIpKQp0aW1lczwtYygiVGltZTEiLCJUaW1lMiIpCgphbGxyZWNvdnMgPC0gYXMuZGF0YS5mcmFtZShtYXRyaXgobmNvbD0xNCxucm93PTApKQoKUXVhZGRpcnMgPC0gbGlzdC5kaXJzKHBhdGggPSAiLiIsIGZ1bGwubmFtZXMgPSBUUlVFLCByZWN1cnNpdmUgPSBUUlVFKVstMV0KZm9yKGQgaW4gUXVhZGRpcnMpewogIGZvcih0aSBpbiB0aW1lcyl7CiAgICBjdXJGaWxlcyA8LSBsaXN0LmZpbGVzKHBhdGg9ZCxwYXR0ZXJuPSJcXC5jc3YkIikKICAgIGlkPC1ncmVwKHRpLGN1ckZpbGVzKQogICAgb3V0cHV0PC1yZWFkLmNzdihwYXN0ZTAoZCwiLyIsY3VyRmlsZXNbaWRdKSkKICAgIG5hbWU8LWdzdWIoIi4vIiwiIixkKQogICAgbmFtZTwtZ3N1YigiICIsIiIsbmFtZSkKICAgIAogICAgaWYodGk9PSJUaW1lMSIpewogICAgICAjY29sbmFtZXMob3V0cHV0KSA8LSBwYXN0ZShjb2xuYW1lcyhvdXRwdXQpLCJUMSIsc2VwPSJfIikKICAgICAgb3V0cHV0JHRpbWUgPC0gIlQxIgogICAgfWVsc2UgaWYodGk9PSJUaW1lMiIpewogICAgICAjY29sbmFtZXMob3V0cHV0KSA8LSBwYXN0ZShjb2xuYW1lcyhvdXRwdXQpLCJUMiIsc2VwPSJfIikKICAgICAgb3V0cHV0JHRpbWUgPC0gIlQyIgogICAgfQogICAgCiAgICBhc3NpZ24ocGFzdGUwKG5hbWUsIi5RdWFkLlJlY292LiIsdGkpLG91dHB1dCkKICB9CiAgZGYgPC0gcmJpbmQoZ2V0KHBhc3RlMChuYW1lLCIuUXVhZC5SZWNvdi5UaW1lMSIpKSxnZXQocGFzdGUwKG5hbWUsIi5RdWFkLlJlY292LlRpbWUyIikpKQogIGFzc2lnbihwYXN0ZTAobmFtZSwiLlF1YWQuUmVjb3YiKSxkZikKICBhbGxyZWNvdnMgPC0gcmJpbmQoYWxscmVjb3ZzLGNiaW5kKGRmLFN0dWR5PW5hbWUpKQp9CgoKYWxscmVjb3ZzJFN0dWR5IDwtIGdzdWIoIkxhaTEiLCAiTGFpIDEiLCBhbGxyZWNvdnMkU3R1ZHkpCmFsbHJlY292cyRTdHVkeSA8LSBnc3ViKCJMYWkyIiwgIkxhaSAyIiwgYWxscmVjb3ZzJFN0dWR5KQpRdWFkLnJlY292cyA8LSBhbGxyZWNvdnMKUXVhZC5yZWNvdnMgPC0gZHBseXI6OnJlbmFtZShRdWFkLnJlY292cywgc3ViSUQ9WCkKCnRhcHBseShRdWFkLnJlY292cyRBQ2JiMSwgUXVhZC5yZWNvdnMkU3R1ZHksIGZ1bmN0aW9uKHgpIGxlbmd0aCh4KSkKYGBgCgpgYGB7cn0KcGF0aCA8LSAiL1ZvbHVtZXMvIgpzZXR3ZChwYXN0ZTAocGF0aCwiUmVzZWFyY2ggUHJvamVjdC9JQVRfUmV0ZXN0L0VzdGltYXRlcy9VQ1IvIikpCkNhbDEgPC1yZWFkLmNzdigiSW5kaXZpZHVhbFBhcmFtZXRlcnNRdWFkVUNSMS5jc3YiLCBoZWFkZXIgPSBUKQpDYWwyIDwtcmVhZC5jc3YoIkluZGl2aWR1YWxQYXJhbWV0ZXJzUXVhZFVDUjIuY3N2IiwgaGVhZGVyID0gVCkKCkNhbDEkdGltZSA8LSAiVDEiCkNhbDIkdGltZSA8LSAiVDIiCkNhbDEkc3ViSUQgPC0gMTpucm93KENhbDEpCkNhbDIkc3ViSUQgPC0gMTpucm93KENhbDIpClAuQ2FsIDwtIHJiaW5kKENhbDEsIENhbDIpCgpzZXR3ZChwYXN0ZTAocGF0aCwiUmVzZWFyY2ggUHJvamVjdC9JQVRfUmV0ZXN0L0VzdGltYXRlcy9QSS8iKSkKUEkxIDwtIHJlYWQuY3N2KCJJbmRpdmlkdWFsUGFyYW1ldGVyc1F1YWRQcm9qZWN0SW1wbGljaXQxLmNzdiIpClBJMiA8LSByZWFkLmNzdigiSW5kaXZpZHVhbFBhcmFtZXRlcnNRdWFkUHJvamVjdEltcGxpY2l0Mi5jc3YiKQoKUEkxJHRpbWUgPC0gIlQxIgpQSTIkdGltZSA8LSAiVDIiClBJMSRzdWJJRCA8LSAxOm5yb3coUEkxKQpQSTIkc3ViSUQgPC0gMTpucm93KFBJMikKUC5QSSA8LSByYmluZChQSTEsIFBJMikKCnNldHdkKHBhc3RlMChwYXRoLCJSZXNlYXJjaCBQcm9qZWN0L0lBVF9SZXRlc3QvRXN0aW1hdGVzL0dhd3JvbnNraS8iKSkKR2F3MSA8LSByZWFkLmNzdigiSW5kaXZpZHVhbFBhcmFtZXRlcnNRdWFkR2F3cm9uc2tpMS5jc3YiKQpHYXcyIDwtIHJlYWQuY3N2KCJJbmRpdmlkdWFsUGFyYW1ldGVyc1F1YWRHYXdyb25za2kyLmNzdiIpCgpHYXcxJHRpbWUgPC0gIlQxIgpHYXcyJHRpbWUgPC0gIlQyIgpHYXcxJHN1YklEIDwtIDE6bnJvdyhHYXcxKQpHYXcyJHN1YklEIDwtIDE6bnJvdyhHYXcyKQpQLkdhdyA8LSByYmluZChHYXcxLCBHYXcyKQoKc2V0d2QocGFzdGUwKHBhdGgsIlJlc2VhcmNoIFByb2plY3QvSUFUX1JldGVzdC9Fc3RpbWF0ZXMvRm9yc2NoZXIvIikpCkZvcjE8LXJlYWQuY3N2KCJJbmRpdmlkdWFsUGFyYW1ldGVyc1F1YWRGb3JzY2hlcjEuY3N2IiwgaGVhZGVyID0gVCkKRm9yMjwtcmVhZC5jc3YoIkluZGl2aWR1YWxQYXJhbWV0ZXJzUXVhZEZvcnNjaGVyMi5jc3YiLCBoZWFkZXIgPSBUKQoKRm9yMSR0aW1lIDwtICJUMSIKRm9yMiR0aW1lIDwtICJUMiIKRm9yMSRzdWJJRCA8LSAxOm5yb3coRm9yMSkKRm9yMiRzdWJJRCA8LSAxOm5yb3coRm9yMikKUC5Gb3IgPC0gcmJpbmQoRm9yMSwgRm9yMikKCnNldHdkKHBhc3RlMChwYXRoLCJSZXNlYXJjaCBQcm9qZWN0L0lBVF9SZXRlc3QvRXN0aW1hdGVzL0xhaTEvIikpCkxhaTExPC1yZWFkLmNzdigiSW5kaXZpZHVhbFBhcmFtZXRlcnNMYWlTdHVkeTFRdWFkMS5jc3YiLCBoZWFkZXIgPSBUKQpMYWkxMjwtcmVhZC5jc3YoIkluZGl2aWR1YWxQYXJhbWV0ZXJzTGFpU3R1ZHkxUXVhZDIuY3N2IiwgaGVhZGVyID0gVCkKCkxhaTExJHRpbWUgPC0gIlQxIgpMYWkxMiR0aW1lIDwtICJUMiIKTGFpMTEkc3ViSUQgPC0gMTpucm93KExhaTExKQpMYWkxMiRzdWJJRCA8LSAxOm5yb3coTGFpMTIpClAuTGFpMSA8LSByYmluZChMYWkxMSwgTGFpMTIpCgpzZXR3ZChwYXN0ZTAocGF0aCwiUmVzZWFyY2ggUHJvamVjdC9JQVRfUmV0ZXN0L0VzdGltYXRlcy9MYWkyLyIpKQpMYWkyMTwtcmVhZC5jc3YoIkluZGl2aWR1YWxQYXJhbWV0ZXJzTGFpU3R1ZHkyUXVhZDEuY3N2IiwgaGVhZGVyID0gVCkKTGFpMjI8LXJlYWQuY3N2KCJJbmRpdmlkdWFsUGFyYW1ldGVyc0xhaVN0dWR5MlF1YWQyLmNzdiIsIGhlYWRlciA9IFQpCgpMYWkyMSR0aW1lIDwtICJUMSIKTGFpMjIkdGltZSA8LSAiVDIiCkxhaTIxJHN1YklEIDwtIDE6bnJvdyhMYWkyMSkKTGFpMjIkc3ViSUQgPC0gMTpucm93KExhaTIyKQpQLkxhaTIgPC0gcmJpbmQoTGFpMjEsTGFpMjIpCgpjb2xuYW1lcyhQLkNhbClbMV0gPC0gInN1YklEIgpQLkNhbCA8LSBjYmluZChQLkNhbCwgU3R1ZHkgPSAiQ2FsYW5jaGluaSIpCmNvbG5hbWVzKFAuUEkpWzFdIDwtICJzdWJJRCIKUC5QSSA8LSBjYmluZChQLlBJLCBTdHVkeSA9ICJQSSIpCmNvbG5hbWVzKFAuR2F3KVsxXSA8LSAic3ViSUQiClAuR2F3IDwtIGNiaW5kKFAuR2F3LCBTdHVkeSA9ICJHYXdyb25za2kiKQpjb2xuYW1lcyhQLkZvcilbMV0gPC0gInN1YklEIgpQLkZvciA8LSBjYmluZChQLkZvciwgU3R1ZHkgPSAiRm9yc2NoZXIiKQpjb2xuYW1lcyhQLkxhaTEpWzFdIDwtICJzdWJJRCIKUC5MYWkxIDwtIGNiaW5kKFAuTGFpMSwgU3R1ZHkgPSAiTGFpIDEiKQpjb2xuYW1lcyhQLkxhaTIpWzFdIDwtICJzdWJJRCIKUC5MYWkyIDwtIGNiaW5kKFAuTGFpMiwgU3R1ZHkgPSAiTGFpIDIiKQoKUXVhZC5vcmlnIDwtIHJiaW5kKFAuQ2FsLFAuUEksUC5HYXcsUC5Gb3IsUC5MYWkxLFAuTGFpMikKUXVhZC5vcmlnWzFdIDwtIE5VTEwKYGBgCgpgYGB7cn0KY29sbmFtZXMoUXVhZC5yZWNvdnMpWzI6IChuY29sKFF1YWQucmVjb3ZzKS0yKSBdIDwtIHBhc3RlKGNvbG5hbWVzKFF1YWQucmVjb3ZzKVsyOiAobmNvbChRdWFkLnJlY292cyktMikgXSwiUiIsc2VwPSJfIikKY29sbmFtZXMoUXVhZC5vcmlnKVsxOiAobmNvbChRdWFkLm9yaWcpLTMpIF0gPC0gcGFzdGUoY29sbmFtZXMoUXVhZC5vcmlnKVsxOiAobmNvbChRdWFkLm9yaWcpLTMpIF0sIk8iLHNlcD0iXyIpClF1YWQub3JpZyA8LSBRdWFkLm9yaWdbb3JkZXIoUXVhZC5vcmlnJFN0dWR5LCBRdWFkLm9yaWckdGltZSksXQpRdWFkLnJlY292cyA8LSBRdWFkLnJlY292c1tvcmRlcihRdWFkLnJlY292cyRTdHVkeSwgUXVhZC5yZWNvdnMkdGltZSksXQoKI1F1YWQub3JpZy5yZWNvdnMgPC0gY2JpbmQoUXVhZC5vcmlnLFF1YWQucmVjb3ZzKQpRdWFkLm9yaWcucmVjb3ZzIDwtIG1lcmdlKFF1YWQub3JpZywgUXVhZC5yZWNvdnMsIGJ5ID0gYygic3ViSUQiLCJTdHVkeSIsInRpbWUiKSkKClF1YWQub3JpZy5yZWNvdnMkU3R1ZHlbUXVhZC5vcmlnLnJlY292cyRTdHVkeT09IlBJIl08LSJQcm9qZWN0IEltcGxpY2l0LCAyMDIwIgpRdWFkLm9yaWcucmVjb3ZzJFN0dWR5W1F1YWQub3JpZy5yZWNvdnMkU3R1ZHk9PSJDYWxhbmNoaW5pIl08LSJXaWxzb24gJiBDYWxhbmNoaW5pLCAyMDIyIgpRdWFkLm9yaWcucmVjb3ZzJFN0dWR5W1F1YWQub3JpZy5yZWNvdnMkU3R1ZHk9PSJMYWkgMSJdPC0iTGFpIGV0IGFsLiwgMjAxNiAoU3R1ZHkgMSkgICIKUXVhZC5vcmlnLnJlY292cyRTdHVkeVtRdWFkLm9yaWcucmVjb3ZzJFN0dWR5PT0iTGFpIDIiXTwtIkxhaSBldCBhbC4sIDIwMTYgKFN0dWR5IDIpICAiClF1YWQub3JpZy5yZWNvdnMkU3R1ZHlbUXVhZC5vcmlnLnJlY292cyRTdHVkeT09Ikdhd3JvbnNraSJdPC0iR2F3cm9uc2tpIGV0IGFsLiwgMjAxNyIKUXVhZC5vcmlnLnJlY292cyRTdHVkeVtRdWFkLm9yaWcucmVjb3ZzJFN0dWR5PT0iRm9yc2NoZXIiXTwtIkZvcnNjaGVyIGV0IGFsLiwgMjAxNyIKYGBgCgojIyBRdWFkIE1vZGVsCgojIyMgQXNzb2NpYXRlIEJsYWNrLUJhZAoKYGBge3J9CkFDYmJTY2F0dGVyIDwtIGdncGxvdChRdWFkLm9yaWcucmVjb3ZzLCBhZXMoeD1BQ2JiMV9PLCB5PUFDYmIxX1IsIGNvbG9yPVN0dWR5LCBzaGFwZT10aW1lKSkgKyAKICBnZW9tX3BvaW50KGFscGhhID0gLjIpKwogIGdlb21fc21vb3RoKG1ldGhvZD1sbSwgc2U9VFJVRSwgbGluZXR5cGU9ImRhc2hlZCIsCiAgICAgICAgICAgICBjb2xvcj0iZ3JleSIpICArIGdlb21fYWJsaW5lKGludGVyY2VwdCA9IDAsIHNsb3BlID0gMSkgKyB5bGltKDAsMSkgKyB4bGltKDAsMSkgKyBsYWJzKHRpdGxlPSJBc3NvY2lhdGlvbiBCbGFjay1CYWQiLAogICAgICAgeD0iT3JpZ2luYWwiLCB5ID0gIlJlY292ZXJlZCIpICsgZ3VpZGVzKGNvbG91ciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KGFscGhhID0gMSkpKSArCiAganRvb2xzOjp0aGVtZV9hcGEoKQpBQ2JiU2NhdHRlcgpnZ3NhdmUocGFzdGUwKHNhdmV0bywiQUNiYlNjYXR0ZXJSRUMuanBnIiksZHBpPTYwMCkKZ2dzYXZlKHBhc3RlMChzYXZldG8sIkFDYmJTY2F0dGVyUkVDLnRpZmYiKSxkcGk9NjAwKQpgYGAKCiMjIyBBc3NvY2lhdGUgV2hpdGUtR29vZAoKYGBge3J9CkFDd2dTY2F0dGVyIDwtIGdncGxvdChRdWFkLm9yaWcucmVjb3ZzLCBhZXMoeD1BQ3dnMV9PLCB5PUFDd2cxX1IsIGNvbG9yPVN0dWR5LCBzaGFwZT10aW1lKSkgKyAKICBnZW9tX3BvaW50KGFscGhhID0gLjIpKwogIGdlb21fc21vb3RoKG1ldGhvZD1sbSwgc2U9VFJVRSwgbGluZXR5cGU9ImRhc2hlZCIsCiAgICAgICAgICAgICBjb2xvcj0iZ3JleSIpICArIGdlb21fYWJsaW5lKGludGVyY2VwdCA9IDAsIHNsb3BlID0gMSkgKyB5bGltKDAsMSkgKyB4bGltKDAsMSkgKyBsYWJzKHRpdGxlPSJBc3NvY2lhdGlvbiBXaGl0ZS1Hb29kIiwKICAgICAgIHg9Ik9yaWdpbmFsIiwgeSA9ICJSZWNvdmVyZWQiKSArIGd1aWRlcyhjb2xvdXIgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChhbHBoYSA9IDEpKSkgKwogIGp0b29sczo6dGhlbWVfYXBhKCkKQUN3Z1NjYXR0ZXIKZ2dzYXZlKHBhc3RlMChzYXZldG8sIkFDd2dTY2F0dGVyUkVDLmpwZyIpLGRwaT02MDApCmdnc2F2ZShwYXN0ZTAoc2F2ZXRvLCJBQ3dnU2NhdHRlclJFQy50aWZmIiksZHBpPTYwMCkKYGBgCgojIyMgRGV0ZWN0aW9uCgpgYGB7cn0KRFNjYXR0ZXIgPC0gZ2dwbG90KFF1YWQub3JpZy5yZWNvdnMsIGFlcyh4PUQxX08sIHk9RDFfUiwgY29sb3I9U3R1ZHksIHNoYXBlPXRpbWUpKSArIAogIGdlb21fcG9pbnQoYWxwaGEgPSAuMikrCiAgZ2VvbV9zbW9vdGgobWV0aG9kPWxtLCBzZT1UUlVFLCBsaW5ldHlwZT0iZGFzaGVkIiwKICAgICAgICAgICAgIGNvbG9yPSJncmV5IikgICsgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0ID0gMCwgc2xvcGUgPSAxKSArIHlsaW0oMCwxKSArIHhsaW0oMCwxKSArIGxhYnModGl0bGU9IkRldGVjdGlvbiIsCiAgICAgICB4PSJPcmlnaW5hbCIsIHkgPSAiUmVjb3ZlcmVkIikgKyBndWlkZXMoY29sb3VyID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3QoYWxwaGEgPSAxKSkpICsKICBqdG9vbHM6OnRoZW1lX2FwYSgpCkRTY2F0dGVyCmdnc2F2ZShwYXN0ZTAoc2F2ZXRvLCJEU2NhdHRlclJFQy5qcGciKSxkcGk9NjAwKQpnZ3NhdmUocGFzdGUwKHNhdmV0bywiRFNjYXR0ZXJSRUMudGlmZiIpLGRwaT02MDApCmBgYAoKIyMjIE92ZXJjb21pbmcgQmlhcwoKYGBge3J9Ck9CU2NhdHRlciA8LSBnZ3Bsb3QoUXVhZC5vcmlnLnJlY292cywgYWVzKHg9T0IxX08sIHk9T0IxX1IsIGNvbG9yPVN0dWR5LCBzaGFwZT10aW1lKSkgKyAKICBnZW9tX3BvaW50KGFscGhhID0gLjIpKwogIGdlb21fc21vb3RoKG1ldGhvZD1sbSwgc2U9VFJVRSwgbGluZXR5cGU9ImRhc2hlZCIsCiAgICAgICAgICAgICBjb2xvcj0iZ3JleSIpICArIGdlb21fYWJsaW5lKGludGVyY2VwdCA9IDAsIHNsb3BlID0gMSkgKyB5bGltKDAsMSkgKyB4bGltKDAsMSkgKyBsYWJzKHRpdGxlPSJPdmVyY29taW5nIEJpYXMiLAogICAgICAgeD0iT3JpZ2luYWwiLCB5ID0gIlJlY292ZXJlZCIpICsgZ3VpZGVzKGNvbG91ciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KGFscGhhID0gMSkpKSArCiAganRvb2xzOjp0aGVtZV9hcGEoKQpPQlNjYXR0ZXIKZ2dzYXZlKHBhc3RlMChzYXZldG8sIk9CU2NhdHRlclJFQy5qcGciKSxkcGk9NjAwKQpnZ3NhdmUocGFzdGUwKHNhdmV0bywiT0JTY2F0dGVyUkVDLnRpZmYiKSxkcGk9NjAwKQpgYGAKCiMjIyBHdWVzc2luZwoKYGBge3J9CkdTY2F0dGVyIDwtIGdncGxvdChRdWFkLm9yaWcucmVjb3ZzLCBhZXMoeD1HMV9PLCB5PUcxX1IsIGNvbG9yPVN0dWR5LCBzaGFwZT10aW1lKSkgKyAKICBnZW9tX3BvaW50KGFscGhhID0gLjIpKwogIGdlb21fc21vb3RoKG1ldGhvZD1sbSwgc2U9VFJVRSwgbGluZXR5cGU9ImRhc2hlZCIsCiAgICAgICAgICAgICBjb2xvcj0iZ3JleSIpICArIGdlb21fYWJsaW5lKGludGVyY2VwdCA9IDAsIHNsb3BlID0gMSkgKyB5bGltKDAsMSkgKyB4bGltKDAsMSkgKyBsYWJzKHRpdGxlPSJHdWVzc2luZyIsCiAgICAgICB4PSJPcmlnaW5hbCIsIHkgPSAiUmVjb3ZlcmVkIikgKyBndWlkZXMoY29sb3VyID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3QoYWxwaGEgPSAxKSkpICsKICBqdG9vbHM6OnRoZW1lX2FwYSgpCkdTY2F0dGVyCmdnc2F2ZShwYXN0ZTAoc2F2ZXRvLCJHU2NhdHRlci5qcGciKSxkcGk9NjAwKQpnZ3NhdmUocGFzdGUwKHNhdmV0bywiR1NjYXR0ZXIudGlmZiIpLGRwaT02MDApCmBgYAoKIyMjIFBhbmVsCgpgYGB7cn0KbGlicmFyeShnZ3B1YnIpClF1YWRQYW5lbDEgPC0gZ2dhcnJhbmdlKEFDd2dTY2F0dGVyLCBBQ2JiU2NhdHRlciwgRFNjYXR0ZXIsIE9CU2NhdHRlciwgR1NjYXR0ZXIsCiAgICAgICAgICBuY29sID0gMywgbnJvdyA9IDIsIGNvbW1vbi5sZWdlbmQgPSBUKQpRdWFkUGFuZWwxCgpyZXF1aXJlKGdyaWQpICAgIyBmb3IgdGhlIHRleHRHcm9iKCkgZnVuY3Rpb24KClF1YWRQYW5lbDIgPC0gZ2dhcnJhbmdlKEFDd2dTY2F0dGVyICArIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xMikpICArIHRoZW1lKGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4KSkgKyBycmVtb3ZlKCJ5bGFiIikgKyBycmVtb3ZlKCJ4bGFiIiksIAogICAgICAgICAgICAgICAgICAgICAgICBBQ2JiU2NhdHRlciAgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTIpKSArIHJyZW1vdmUoInlsYWIiKSArIHJyZW1vdmUoInhsYWIiKSwKICAgICAgICAgICAgICAgICAgICAgICAgRFNjYXR0ZXIgICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSkgKyBycmVtb3ZlKCJ5bGFiIikgKyBycmVtb3ZlKCJ4bGFiIiksCiAgICAgICAgICAgICAgICAgICAgICAgIE9CU2NhdHRlciAgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTIpKSArIHJyZW1vdmUoInlsYWIiKSArIHJyZW1vdmUoInhsYWIiKSwKICAgICAgICAgICAgICAgICAgICAgICAgR1NjYXR0ZXIgICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSkgKyBycmVtb3ZlKCJ5bGFiIikgKyBycmVtb3ZlKCJ4bGFiIiksCiAgICAgICAgICBuY29sID0gMywgbnJvdyA9IDIsIGNvbW1vbi5sZWdlbmQgPSBULCBsYWJlbHMgPSBOVUxMLCBsZWdlbmQgPSAiYm90dG9tIiwKICAgICAgICAgIGFsaWduID0gImh2IiwgCiAgICAgICAgICAgICAgICAgICAgZm9udC5sYWJlbCA9IGxpc3Qoc2l6ZSA9IDEwLCBjb2xvciA9ICJibGFjayIsIGZhY2UgPSAiYm9sZCIsIGZhbWlseSA9IE5VTEwsIHBvc2l0aW9uID0gInRvcCIpKQpRdWFkUGFuZWwyCgphbm5vdGF0ZV9maWd1cmUoUXVhZFBhbmVsMiwgbGVmdCA9IHRleHRHcm9iKCJSZWNvdmVyZWQiLCByb3QgPSA5MCwgdmp1c3QgPSAxLCBoanVzdCA9IDAsIGdwID0gZ3BhcihjZXggPSAxKSksCiAgICAgICAgICAgICAgICAgICAgYm90dG9tID0gdGV4dEdyb2IoIk9yaWdpbmFsIiwgdmp1c3QgPSAtNi41LCBncCA9IGdwYXIoY2V4ID0gMSkpKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9IGMoMCwtMSkpCmdnc2F2ZShwYXN0ZTAoc2F2ZXRvLCJRdWFkUGFuZWxSRUMuanBnIiksZHBpPTYwMCkKZ2dzYXZlKHBhc3RlMChzYXZldG8sIlF1YWRQYW5lbFJFQy50aWZmIiksZHBpPTYwMCkKYGBgCgojIFJlY292ZXJ5IE1ldGEtQW5hbHlzaXMKCiMjIFF1YWQKCgpgYGB7cn0KZHQgPC0gcmVhZC5jc3YoIn4vRG9jdW1lbnRzL0dpdEh1Yi9NUFQtUmVsaWFiaWxpdHkvUmVjb3Zlcnkvb3V0cHV0L2NvbWJRdWFkX1JlY292ZXJ5X0RmLmNzdiIpWzI6N10KZHQkaWQgPC0gdW5saXN0KGxhcHBseSgxOjUsIGZ1bmN0aW9uKHgpIHJlcCh4LHRpbWVzPTEzKSkpCgpkdCRQYXJhbVtkdCRQYXJhbT09IkQiXTwtIkRldGVjdGlvbiIKZHQkUGFyYW1bZHQkUGFyYW09PSJPQiJdPC0iT3ZlcmNvbWluZyBCaWFzIgpkdCRQYXJhbVtkdCRQYXJhbT09IkFDYmIiXTwtIkFzc29jaWF0aW9uIEJsYWNrLUJhZCIKZHQkUGFyYW1bZHQkUGFyYW09PSJBQ3dnIl08LSJBc3NvY2lhdGlvbiBXaGl0ZS1Hb29kIgpkdCRQYXJhbVtkdCRQYXJhbT09IkciXTwtIkd1ZXNzaW5nIgoKZHQkUGFyYW1bZHQkUGFyYW09PSJQSSJdPC0iUHJvamVjdCBJbXBsaWNpdCwgMjAyMCIKZHQkUGFyYW1bZHQkUGFyYW09PSJDYWxhbmNoaW5pIl08LSJXaWxzb24gJiBDYWxhbmNoaW5pLCAyMDIyIgpkdCRQYXJhbVtkdCRQYXJhbT09IkxhaTEiXTwtIkxhaSBldCBhbC4sIDIwMTYgKFN0dWR5IDEpICAiCmR0JFBhcmFtW2R0JFBhcmFtPT0iTGFpMiJdPC0iTGFpIGV0IGFsLiwgMjAxNiAoU3R1ZHkgMikgICIKZHQkUGFyYW1bZHQkUGFyYW09PSJHYXdyb25za2kiXTwtIkdhd3JvbnNraSBldCBhbC4sIDIwMTciCmR0JFBhcmFtW2R0JFBhcmFtPT0iRm9yc2NoZXIiXTwtIkZvcnNjaGVyIGV0IGFsLiwgMjAxNyIKCiMgaW5kZW50IHRoZSBzdWJncm91cCBpZiB0aGVyZSBpcyBhIG51bWJlciBpbiB0aGUgcGxhY2VibyBjb2x1bW4KZHQkUGFyYW0gPC0gaWZlbHNlKGR0JHR5cGU9PTAsIAogICAgICAgICAgICAgICAgICAgICAgZHQkUGFyYW0sCiAgICAgICAgICAgICAgICAgICAgICBwYXN0ZTAoIiAiLCBkdCRQYXJhbSkpCgpkdCRgIGAgPC0gcGFzdGUocmVwKCIgIiwgMjApLCBjb2xsYXBzZSA9ICIgIikKZHQkYFJlY292ZXJ5ICg5NSUgQ0kpYCA8LSBpZmVsc2UoaXMubmEoZHQkUmVjb3YpLCAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcHJpbnRmKCIlLjJmIFslLjJmLCAlLjJmXSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkdCRSZWNvdiwgZHQkQ0kuTEIsIGR0JENJLlVCKSkKCmR0MiA8LSBwaXZvdF93aWRlcihkdCwgaWRfY29scyA9IGMoIlBhcmFtIiwiaWQiKSwgIG5hbWVzX2Zyb20gPSBjKFRpbWUpLCB2YWx1ZXNfZnJvbSA9IGMoUmVjb3YsQ0kuTEIsQ0kuVUIsYFJlY292ZXJ5ICg5NSUgQ0kpYCkgKQpkdDIkYFJlY292ZXJ5IFs5NSUgQ0ldYCA8LSBpZmVsc2UoIWlzLm5hKGR0MiRgUmVjb3ZlcnkgKDk1JSBDSSlfTWV0YWApLCBwYXN0ZTAoIiAgICAgICAgICAgICAgICAgIixkdDIkYFJlY292ZXJ5ICg5NSUgQ0kpX01ldGFgKSwgcGFzdGUwKCJUMSA6IiwgcGFzdGUwKGR0MiRgUmVjb3ZlcnkgKDk1JSBDSSlfVGltZTFgKSwgIiA7ICIsICJUMjogIiwgcGFzdGUwKGR0MiRgUmVjb3ZlcnkgKDk1JSBDSSlfVGltZTJgKSkpCmR0MiRgIGAgPC0gcGFzdGUocmVwKCIgIiwgMjApLCBjb2xsYXBzZSA9ICIgIikKCgpkdDM8LWR0MiAlPiUgc2VsZWN0KFBhcmFtLFJlY292X01ldGE6MTEsMTUsMTYpCgpjb2xuYW1lcyhkdDMpW2NvbG5hbWVzKGR0Myk9PSJQYXJhbSJdIDwtICIgICAiCmNvbG5hbWVzKGR0MylbY29sbmFtZXMoZHQzKT09IlJlY292ZXJ5IFs5NSUgQ0ldIl0gPC0gIiAgICAiCgpkdDMkc2l6ZV9NZXRhIDwtIGlmZWxzZShpcy5uYShkdDMkUmVjb3ZfTWV0YSksIE5BLCAxLjIpCmR0MyRzaXplX1QxIDwtIGlmZWxzZShpcy5uYShkdDMkUmVjb3ZfVGltZTEpLCBOQSwgLjYpCmR0MyRzaXplX1QyIDwtIGlmZWxzZShpcy5uYShkdDMkUmVjb3ZfVGltZTIpLCBOQSwgLjYpCgojIFNldC11cCB0aGVtZQp0bSA8LSBmb3Jlc3RfdGhlbWUoCiAgICAgICAgICAgICAgICAgICBjaV9wY2ggPSBjKDE1LCAxNiwgMTcpLAogICAgICAgICAgICAgICAgICAgY2lfY29sID0gYygiYmxhY2siLCJyZWQiLCJibHVlIiksCiAgICAgICAgICAgICAgICAgICBjaV9sdHkgPSBjKCAic29saWQiLCAiZGFzaGVkIiwgImRvdHRlZCIpLAogICAgICAgICAgICAgICAgICAjIGZvb3Rub3RlX2NvbCA9ICJibHVlIiwKICAgICAgICAgICAgICAgICAgIGxlZ2VuZF9uYW1lID0gIiAiLAogICAgICAgICAgICAgICAgICBsZWdlbmRfcG9zaXRpb24gPSAiYm90dG9tIiwKICAgICAgICAgICAgICAgICAgIGxlZ2VuZF92YWx1ZSA9IGMoIk1ldGEtQW5hbHlzaXMgIiwgIlRpbWUgMSAiLCAiVGltZSAyICIpKQoKbGlicmFyeShmb3Jlc3RwbG90ZXIpCnAgPC0gZm9yZXN0KAogIGR0M1tjKDEsMTIsMTEpXSwKICAgICAgICAgICAgZXN0ID0gbGlzdChkdDMkUmVjb3ZfTWV0YSwgZHQzJFJlY292X1RpbWUxLCBkdDMkUmVjb3ZfVGltZTIpLAogICAgICAgICAgICBsb3dlciA9IGxpc3QoZHQzJENJLkxCX01ldGEsIGR0MyRDSS5MQl9UaW1lMSwgZHQzJENJLkxCX1RpbWUyKSwgCiAgICAgICAgICAgIHVwcGVyID0gbGlzdChkdDMkQ0kuVUJfTWV0YSwgZHQzJENJLlVCX1RpbWUxLCBkdDMkQ0kuVUJfVGltZTIpLAogICAgICAgICAgICBjaV9jb2x1bW4gPSAyLAogICAgICAgICAgICByZWZfbGluZSA9IC43LAogICAgICAgICAgICB4bGltID0gYygtLjEsIDEpLAogICAgICAgICAgICB0aWNrc19hdCA9IGMoMCwgLjIsIC41LCAuNywgMSksCiAgc2l6ZXMgPSBsaXN0KGR0MyRzaXplX01ldGEsIGR0MyRzaXplX1QxLCBkdDMkc2l6ZV9UMiksCiAgdGhlbWUgPSB0bQopCnBsb3QocCkKCmxpYnJhcnkoZ3JpZCkKcCA8LSBlZGl0X3Bsb3QocCwKICAgICAgICAgICAgICAgcm93ID0gc2VxKGZyb209MSx0bz1ucm93KGR0MyksYnk9NyksCiAgICAgICAgICAgICAgIGdwID0gZ3Bhcihmb250ZmFjZSA9IGMoImJvbGQiLCJpdGFsaWMiKQogICAgICAgICAgICAgICAgICAgICAgICAgKSwgY29sID0gMSkKCnN0dWR5SW5kcyA8LSBzZXRkaWZmKDE6bnJvdyhkdDMpLHNlcShmcm9tPTEsdG89bnJvdyhkdDMpLGJ5PTcpKQpwYXJhbUluZHMgPC0gc2VxKGZyb209MSx0bz1ucm93KGR0KSxieT03KQoKcCA8LSBlZGl0X3Bsb3QocCwgcm93ID0gc3R1ZHlJbmRzLCB3aGljaCA9ICJiYWNrZ3JvdW5kIiwKICAgICAgICAgICAgICAgZ3AgPSBncGFyKGZpbGwgPSAid2hpdGUiKSkKcCA8LSBlZGl0X3Bsb3QocCwgcm93ID0gcGFyYW1JbmRzLCB3aGljaCA9ICJiYWNrZ3JvdW5kIiwKICAgICAgICAgICAgICAgZ3AgPSBncGFyKGZpbGwgPSAiZ3JleSIpKQoKYGBgCgpgYGB7cn0KcG5nKCJ+L0Rlc2t0b3AvUXVhZF9SZWNvdkZvcmVzdC5wbmciLCB1bml0cz0iaW4iLCB3aWR0aD0xMCwgaGVpZ2h0PTE1LCByZXM9MzAwKQpwbG90KHApCmRldi5vZmYoKQpgYGAKCmBgYHtyfQojIGdnc2F2ZSBmdW5jdGlvbgpnZ3Bsb3QyOjpnZ3NhdmUocGFzdGUwKHNhdmV0bywiUXVhZF9SZWNvdkZvcmVzdC5wbmciKSwKICAgICAgICAgICAgICAgIGRwaSA9IDMwMCwKICAgICAgICAgICAgICAgIHdpZHRoID0gOCwgaGVpZ2h0ID0gMTUsIHVuaXRzID0gImluIiwgcGxvdD1wKQoKZ2dwbG90Mjo6Z2dzYXZlKHBhc3RlMChzYXZldG8sIlF1YWRfUmVjb3ZGb3Jlc3QudGlmZiIpLAogICAgICAgICAgICAgICAgZHBpID0gMzAwLAogICAgICAgICAgICAgICAgd2lkdGggPSA4LCBoZWlnaHQgPSAxNSwgdW5pdHMgPSAiaW4iLCBwbG90PXApCmBgYAoKCmBgYHtyfQpkdCA8LSByZWFkLmNzdigifi9Eb2N1bWVudHMvR2l0SHViL01QVC1SZWxpYWJpbGl0eS9SZWNvdmVyeS9vdXRwdXQvY29tYlBEX1JlY292ZXJ5X0RmLmNzdiIpWzI6N10KZHQkaWQgPC0gdW5saXN0KGxhcHBseSgxOjYsIGZ1bmN0aW9uKHgpIHJlcCh4LHRpbWVzPTEzKSkpCgpkdCRQYXJhbVtkdCRQYXJhbT09IkFiIl08LSJBdXRvbWF0aWMgQmxhY2siCmR0JFBhcmFtW2R0JFBhcmFtPT0iQXciXTwtIkF1dG9tYXRpYyBXaGl0ZSIKZHQkUGFyYW1bZHQkUGFyYW09PSJDYiJdPC0iQ29udHJvbCBCbGFjayIKZHQkUGFyYW1bZHQkUGFyYW09PSJDdyJdPC0iQ29udHJvbCBXaGl0ZSIKZHQkUGFyYW1bZHQkUGFyYW09PSJDdSJdPC0iQ29udHJvbCBCYWQiCmR0JFBhcmFtW2R0JFBhcmFtPT0iQ3AiXTwtIkNvbnRyb2wgR29vZCIKCmR0JFBhcmFtW2R0JFBhcmFtPT0iUEkiXTwtIlByb2plY3QgSW1wbGljaXQsIDIwMjAiCmR0JFBhcmFtW2R0JFBhcmFtPT0iQ2FsYW5jaGluaSJdPC0iV2lsc29uICYgQ2FsYW5jaGluaSwgMjAyMiIKZHQkUGFyYW1bZHQkUGFyYW09PSJMYWkxIl08LSJMYWkgZXQgYWwuLCAyMDE2IChTdHVkeSAxKSAgIgpkdCRQYXJhbVtkdCRQYXJhbT09IkxhaTIiXTwtIkxhaSBldCBhbC4sIDIwMTYgKFN0dWR5IDIpICAiCmR0JFBhcmFtW2R0JFBhcmFtPT0iR2F3cm9uc2tpIl08LSJHYXdyb25za2kgZXQgYWwuLCAyMDE3IgpkdCRQYXJhbVtkdCRQYXJhbT09IkZvcnNjaGVyIl08LSJGb3JzY2hlciBldCBhbC4sIDIwMTciCgojIGluZGVudCB0aGUgc3ViZ3JvdXAgaWYgdGhlcmUgaXMgYSBudW1iZXIgaW4gdGhlIHBsYWNlYm8gY29sdW1uCmR0JFBhcmFtIDwtIGlmZWxzZShkdCR0eXBlPT0wLCAKICAgICAgICAgICAgICAgICAgICAgIGR0JFBhcmFtLAogICAgICAgICAgICAgICAgICAgICAgcGFzdGUwKCIgIiwgZHQkUGFyYW0pKQoKZHQkYCBgIDwtIHBhc3RlKHJlcCgiICIsIDIwKSwgY29sbGFwc2UgPSAiICIpCmR0JGBSZWNvdmVyeSAoOTUlIENJKWAgPC0gaWZlbHNlKGlzLm5hKGR0JFJlY292KSwgIiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ByaW50ZigiJS4yZiBbJS4yZiwgJS4yZl0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHQkUmVjb3YsIGR0JENJLkxCLCBkdCRDSS5VQikpCgpkdDIgPC0gcGl2b3Rfd2lkZXIoZHQsIGlkX2NvbHMgPSBjKCJQYXJhbSIsImlkIiksICBuYW1lc19mcm9tID0gYyhUaW1lKSwgdmFsdWVzX2Zyb20gPSBjKFJlY292LENJLkxCLENJLlVCLGBSZWNvdmVyeSAoOTUlIENJKWApICkKZHQyJGBSZWNvdmVyeSBbOTUlIENJXWAgPC0gaWZlbHNlKCFpcy5uYShkdDIkYFJlY292ZXJ5ICg5NSUgQ0kpX01ldGFgKSwgcGFzdGUwKCIgICAgICAgICAgICAgICAgICIsZHQyJGBSZWNvdmVyeSAoOTUlIENJKV9NZXRhYCksIHBhc3RlMCgiVDEgOiIsIHBhc3RlMChkdDIkYFJlY292ZXJ5ICg5NSUgQ0kpX1RpbWUxYCksICIgOyAiLCAiVDI6ICIsIHBhc3RlMChkdDIkYFJlY292ZXJ5ICg5NSUgQ0kpX1RpbWUyYCkpKQpkdDIkYCBgIDwtIHBhc3RlKHJlcCgiICIsIDIwKSwgY29sbGFwc2UgPSAiICIpCgoKZHQzPC1kdDIgJT4lIHNlbGVjdChQYXJhbSxSZWNvdl9NZXRhOjExLDE1LDE2KQoKY29sbmFtZXMoZHQzKVtjb2xuYW1lcyhkdDMpPT0iUGFyYW0iXSA8LSAiICAgIgpjb2xuYW1lcyhkdDMpW2NvbG5hbWVzKGR0Myk9PSJSZWNvdmVyeSBbOTUlIENJXSJdIDwtICIgICAgIgoKZHQzJHNpemVfTWV0YSA8LSBpZmVsc2UoaXMubmEoZHQzJFJlY292X01ldGEpLCBOQSwgMS4yKQpkdDMkc2l6ZV9UMSA8LSBpZmVsc2UoaXMubmEoZHQzJFJlY292X1RpbWUxKSwgTkEsIC42KQpkdDMkc2l6ZV9UMiA8LSBpZmVsc2UoaXMubmEoZHQzJFJlY292X1RpbWUyKSwgTkEsIC42KQoKIyBTZXQtdXAgdGhlbWUKdG0gPC0gZm9yZXN0X3RoZW1lKAogICAgICAgICAgICAgICAgICAgY2lfcGNoID0gYygxNSwgMTYsIDE3KSwKICAgICAgICAgICAgICAgICAgIGNpX2NvbCA9IGMoImJsYWNrIiwicmVkIiwiYmx1ZSIpLAogICAgICAgICAgICAgICAgICAgY2lfbHR5ID0gYyggInNvbGlkIiwgImRhc2hlZCIsICJkb3R0ZWQiKSwKICAgICAgICAgICAgICAgICAgIyBmb290bm90ZV9jb2wgPSAiYmx1ZSIsCiAgICAgICAgICAgICAgICAgICBsZWdlbmRfbmFtZSA9ICIgIiwKICAgICAgICAgICAgICAgICAgbGVnZW5kX3Bvc2l0aW9uID0gImJvdHRvbSIsCiAgICAgICAgICAgICAgICAgICBsZWdlbmRfdmFsdWUgPSBjKCJNZXRhLUFuYWx5c2lzICIsICJUaW1lIDEgIiwgIlRpbWUgMiAiKSkKCmxpYnJhcnkoZm9yZXN0cGxvdGVyKQpwIDwtIGZvcmVzdCgKICBkdDNbYygxLDEyLDExKV0sCiAgICAgICAgICAgIGVzdCA9IGxpc3QoZHQzJFJlY292X01ldGEsIGR0MyRSZWNvdl9UaW1lMSwgZHQzJFJlY292X1RpbWUyKSwKICAgICAgICAgICAgbG93ZXIgPSBsaXN0KGR0MyRDSS5MQl9NZXRhLCBkdDMkQ0kuTEJfVGltZTEsIGR0MyRDSS5MQl9UaW1lMiksIAogICAgICAgICAgICB1cHBlciA9IGxpc3QoZHQzJENJLlVCX01ldGEsIGR0MyRDSS5VQl9UaW1lMSwgZHQzJENJLlVCX1RpbWUyKSwKICAgICAgICAgICAgY2lfY29sdW1uID0gMiwKICAgICAgICAgICAgcmVmX2xpbmUgPSAuNywKICAgICAgICAgICAgeGxpbSA9IGMoLS4xLCAxKSwKICAgICAgICAgICAgdGlja3NfYXQgPSBjKDAsIC4yLCAuNSwgLjcsIDEpLAogIHNpemVzID0gbGlzdChkdDMkc2l6ZV9NZXRhLCBkdDMkc2l6ZV9UMSwgZHQzJHNpemVfVDIpLAogIHRoZW1lID0gdG0KKQpwbG90KHApCgpsaWJyYXJ5KGdyaWQpCnAgPC0gZWRpdF9wbG90KHAsCiAgICAgICAgICAgICAgIHJvdyA9IHNlcShmcm9tPTEsdG89bnJvdyhkdDMpLGJ5PTcpLAogICAgICAgICAgICAgICBncCA9IGdwYXIoZm9udGZhY2UgPSBjKCJib2xkIiwiaXRhbGljIikKICAgICAgICAgICAgICAgICAgICAgICAgICksIGNvbCA9IDEpCgpzdHVkeUluZHMgPC0gc2V0ZGlmZigxOm5yb3coZHQzKSxzZXEoZnJvbT0xLHRvPW5yb3coZHQzKSxieT03KSkKcGFyYW1JbmRzIDwtIHNlcShmcm9tPTEsdG89bnJvdyhkdCksYnk9NykKCnAgPC0gZWRpdF9wbG90KHAsIHJvdyA9IHN0dWR5SW5kcywgd2hpY2ggPSAiYmFja2dyb3VuZCIsCiAgICAgICAgICAgICAgIGdwID0gZ3BhcihmaWxsID0gIndoaXRlIikpCnAgPC0gZWRpdF9wbG90KHAsIHJvdyA9IHBhcmFtSW5kcywgd2hpY2ggPSAiYmFja2dyb3VuZCIsCiAgICAgICAgICAgICAgIGdwID0gZ3BhcihmaWxsID0gImdyZXkiKSkKCmBgYAoKYGBge3J9CnBuZygifi9EZXNrdG9wL1BEX1JlY292Rm9yZXN0LnBuZyIsIHVuaXRzPSJpbiIsIHdpZHRoPTEwLCBoZWlnaHQ9MTgsIHJlcz0zMDApCnBsb3QocCkKZGV2Lm9mZigpCmBgYAoKYGBge3J9CiMgZ2dzYXZlIGZ1bmN0aW9uCmdncGxvdDI6Omdnc2F2ZShwYXN0ZTAoc2F2ZXRvLCJQRF9SZWNvdkZvcmVzdC5wbmciKSwKICAgICAgICAgICAgICAgIGRwaSA9IDMwMCwKICAgICAgICAgICAgICAgIHdpZHRoID0gOCwgaGVpZ2h0ID0gMTcsIHVuaXRzID0gImluIiwgcGxvdD1wKQoKZ2dwbG90Mjo6Z2dzYXZlKHBhc3RlMChzYXZldG8sIlBEX1JlY292Rm9yZXN0LnRpZmYiKSwKICAgICAgICAgICAgICAgIGRwaSA9IDYwMCwKICAgICAgICAgICAgICAgIHdpZHRoID0gOCwgaGVpZ2h0ID0gMTcsIHVuaXRzID0gImluIiwgcGxvdD1wKQpgYGA=